NeoMutt  2022-04-29-145-g9b6a0e
Teaching an old dog new tricks
DOXYGEN
Expando API

Prototype for a mutt_expando_format() Callback Function. More...

Functions

static const char * alias_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the alias list - Implements format_t -. More...
 
static const char * query_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the query menu - Implements format_t -. More...
 
const char * attach_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the attachment menu - Implements format_t -. More...
 
static const char * autocrypt_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the Autocrypt account list - Implements format_t -. More...
 
static const char * folder_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the folder browser - Implements format_t -. More...
 
static const char * compress_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Expand the filenames in a command string - Implements format_t -. More...
 
static const char * compose_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Create the status bar string for compose mode - Implements format_t -. More...
 
static const char * index_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the index list - Implements format_t -. More...
 
static const char * history_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the history list - Implements format_t -. More...
 
static const char * mix_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the remailer menu - Implements format_t -. 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...
 
static const char * crypt_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the key selection menu - Implements format_t -. More...
 
static const char * pgp_entry_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format an entry on the PGP key selection menu - Implements format_t -. More...
 
static const char * pgp_command_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a PGP command string - Implements format_t -. More...
 
static const char * smime_command_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format an SMIME command - Implements format_t -. More...
 
const char * group_index_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the newsgroup menu - Implements format_t -. More...
 
const char * nntp_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Expand the newsrc filename - Implements format_t -. More...
 
static const char * pattern_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the pattern completion menu - Implements format_t -. More...
 
static const char * greeting_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a greetings string - Implements format_t -. More...
 
static const char * sidebar_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the sidebar - Implements format_t -. More...
 
static const char * status_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Create the status bar string - Implements format_t -. More...
 

Detailed Description

Prototype for a mutt_expando_format() Callback Function.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]colStarting column
[in]colsNumber of screen columns
[in]opprintf-like operator, e.g. 't'
[in]srcprintf-like format string
[in]precField precision, e.g. "-3.4"
[in]if_strIf condition is met, display this string
[in]else_strOtherwise, display this string
[in]dataPrivate data
[in]flagsFlags, see MuttFormatFlags
Return values
ptrsrc (unchanged)

Each callback function implements some expandos, e.g.

Expando Description
%t Title

Function Documentation

◆ alias_format_str()

static const char* alias_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the alias list - Implements format_t -.

Expando Description
%a Alias name
%c Comments
%f Flags - currently, a 'd' for an alias marked for deletion
%n Index number
%r Address which alias expands to
%t Character which indicates if the alias is tagged for inclusion

Definition at line 124 of file dlg_alias.c.

128 {
129  char fmt[128], addr[1024];
130  struct AliasView *av = (struct AliasView *) data;
131  struct Alias *alias = av->alias;
132 
133  switch (op)
134  {
135  case 'a':
136  mutt_format_s(buf, buflen, prec, alias->name);
137  break;
138  case 'c':
139  mutt_format_s(buf, buflen, prec, alias->comment);
140  break;
141  case 'f':
142  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
143  snprintf(buf, buflen, fmt, av->is_deleted ? "D" : " ");
144  break;
145  case 'n':
146  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
147  snprintf(buf, buflen, fmt, av->num + 1);
148  break;
149  case 'r':
150  addr[0] = '\0';
151  mutt_addrlist_write(&alias->addr, addr, sizeof(addr), true);
152  mutt_format_s(buf, buflen, prec, addr);
153  break;
154  case 't':
155  buf[0] = av->is_tagged ? '*' : ' ';
156  buf[1] = '\0';
157  break;
158  }
159 
160  return src;
161 }
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:790
GUI data wrapping an Alias.
Definition: gui.h:36
struct Alias * alias
Alias.
Definition: gui.h:44
bool is_deleted
Is it deleted?
Definition: gui.h:42
bool is_tagged
Is it tagged?
Definition: gui.h:41
int num
Index number in list.
Definition: gui.h:37
A shortcut for an email address or addresses.
Definition: alias.h:34
char * comment
Free-form comment string.
Definition: alias.h:37
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_format_str()

static const char* query_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the query menu - Implements format_t -.

Expando Description
%a Destination address
%c Current entry number
%e Extra information
%n Destination name
%t * if current entry is tagged, a space otherwise

Definition at line 148 of file dlg_query.c.

152 {
153  struct AliasView *av = (struct AliasView *) data;
154  struct Alias *alias = av->alias;
155  char fmt[128];
156  char tmp[256] = { 0 };
157  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
158 
159  switch (op)
160  {
161  case 'a':
162  tmp[0] = '<';
163  mutt_addrlist_write(&alias->addr, tmp + 1, sizeof(tmp) - 1, true);
164  const size_t len = strlen(tmp);
165  if (len < (sizeof(tmp) - 1))
166  {
167  tmp[len] = '>';
168  tmp[len + 1] = '\0';
169  }
170  mutt_format_s(buf, buflen, prec, tmp);
171  break;
172  case 'c':
173  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
174  snprintf(buf, buflen, fmt, av->num + 1);
175  break;
176  case 'e':
177  if (!optional)
178  mutt_format_s(buf, buflen, prec, NONULL(alias->comment));
179  else if (!alias->comment || (*alias->comment == '\0'))
180  optional = false;
181  break;
182  case 'n':
183  mutt_format_s(buf, buflen, prec, NONULL(alias->name));
184  break;
185  case 't':
186  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
187  snprintf(buf, buflen, fmt, av->is_tagged ? '*' : ' ');
188  break;
189  default:
190  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
191  snprintf(buf, buflen, fmt, op);
192  break;
193  }
194 
195  if (optional)
196  {
197  mutt_expando_format(buf, buflen, col, cols, if_str, query_format_str, data,
199  }
200  else if (flags & MUTT_FORMAT_OPTIONAL)
201  {
202  mutt_expando_format(buf, buflen, col, cols, else_str, query_format_str,
203  data, MUTT_FORMAT_NO_FLAGS);
204  }
205 
206  /* We return the format string, unchanged */
207  return src;
208 }
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
static const char * query_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the query menu - Implements format_t -.
Definition: dlg_query.c:148
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:777
#define NONULL(x)
Definition: string2.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attach_format_str()

const char* attach_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)

Format a string for the attachment menu - Implements format_t -.

Expando Description
%C Character set
%c Character set: convert?
%D Deleted flag
%d Description
%e MIME content-transfer-encoding
%f Filename
%F Filename for content-disposition header
%I Content-disposition, either I (inline) or A (attachment)
%m Major MIME type
%M MIME subtype
%n Attachment number
%Q 'Q', if MIME part qualifies for attachment counting
%s Size
%t Tagged flag
%T Tree chars
%u Unlink
%X Number of qualifying MIME parts in this part and its children

Definition at line 150 of file dlg_attach.c.

153 {
154  char fmt[128];
155  char charset[128];
156  struct AttachPtr *aptr = (struct AttachPtr *) data;
157  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
158 
159  switch (op)
160  {
161  case 'C':
162  if (!optional)
163  {
164  if (mutt_is_text_part(aptr->body) &&
165  mutt_body_get_charset(aptr->body, charset, sizeof(charset)))
166  {
167  mutt_format_s(buf, buflen, prec, charset);
168  }
169  else
170  mutt_format_s(buf, buflen, prec, "");
171  }
172  else if (!mutt_is_text_part(aptr->body) ||
173  !mutt_body_get_charset(aptr->body, charset, sizeof(charset)))
174  {
175  optional = false;
176  }
177  break;
178  case 'c':
179  /* XXX */
180  if (!optional)
181  {
182  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
183  snprintf(buf, buflen, fmt,
184  ((aptr->body->type != TYPE_TEXT) || aptr->body->noconv) ? 'n' : 'c');
185  }
186  else if ((aptr->body->type != TYPE_TEXT) || aptr->body->noconv)
187  optional = false;
188  break;
189  case 'd':
190  {
191  const char *const c_message_format = cs_subset_string(NeoMutt->sub, "message_format");
192  if (!optional)
193  {
194  if (aptr->body->description)
195  {
196  mutt_format_s(buf, buflen, prec, aptr->body->description);
197  break;
198  }
199  if (mutt_is_message_type(aptr->body->type, aptr->body->subtype) &&
200  c_message_format && aptr->body->email)
201  {
202  char s[128];
203  mutt_make_string(s, sizeof(s), cols, c_message_format, NULL, -1,
204  aptr->body->email,
206  if (*s)
207  {
208  mutt_format_s(buf, buflen, prec, s);
209  break;
210  }
211  }
212  if (!aptr->body->d_filename && !aptr->body->filename)
213  {
214  mutt_format_s(buf, buflen, prec, "<no description>");
215  break;
216  }
217  }
218  else if (aptr->body->description ||
219  (mutt_is_message_type(aptr->body->type, aptr->body->subtype) &&
220  c_message_format && aptr->body->email))
221  {
222  break;
223  }
224  }
225  /* fallthrough */
226  case 'F':
227  if (!optional)
228  {
229  if (aptr->body->d_filename)
230  {
231  mutt_format_s(buf, buflen, prec, aptr->body->d_filename);
232  break;
233  }
234  }
235  else if (!aptr->body->d_filename && !aptr->body->filename)
236  {
237  optional = false;
238  break;
239  }
240  /* fallthrough */
241  case 'f':
242  if (!optional)
243  {
244  if (aptr->body->filename && (*aptr->body->filename == '/'))
245  {
246  struct Buffer *path = mutt_buffer_pool_get();
247 
248  mutt_buffer_strcpy(path, aptr->body->filename);
250  mutt_format_s(buf, buflen, prec, mutt_buffer_string(path));
252  }
253  else
254  mutt_format_s(buf, buflen, prec, NONULL(aptr->body->filename));
255  }
256  else if (!aptr->body->filename)
257  optional = false;
258  break;
259  case 'D':
260  if (!optional)
261  snprintf(buf, buflen, "%c", aptr->body->deleted ? 'D' : ' ');
262  else if (!aptr->body->deleted)
263  optional = false;
264  break;
265  case 'e':
266  if (!optional)
267  mutt_format_s(buf, buflen, prec, ENCODING(aptr->body->encoding));
268  break;
269  case 'I':
270  if (optional)
271  break;
272 
273  const char dispchar[] = { 'I', 'A', 'F', '-' };
274  char ch;
275 
276  if (aptr->body->disposition < sizeof(dispchar))
277  ch = dispchar[aptr->body->disposition];
278  else
279  {
280  mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n",
281  aptr->body->disposition);
282  ch = '!';
283  }
284  snprintf(buf, buflen, "%c", ch);
285  break;
286  case 'm':
287  if (!optional)
288  mutt_format_s(buf, buflen, prec, TYPE(aptr->body));
289  break;
290  case 'M':
291  if (!optional)
292  mutt_format_s(buf, buflen, prec, aptr->body->subtype);
293  else if (!aptr->body->subtype)
294  optional = false;
295  break;
296  case 'n':
297  if (optional)
298  break;
299 
300  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
301  snprintf(buf, buflen, fmt, aptr->num + 1);
302  break;
303  case 'Q':
304  if (optional)
305  optional = aptr->body->attach_qualifies;
306  else
307  {
308  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
309  mutt_format_s(buf, buflen, fmt, "Q");
310  }
311  break;
312  case 's':
313  {
314  size_t l = 0;
315  if (aptr->body->filename && (flags & MUTT_FORMAT_STAT_FILE))
316  {
317  l = mutt_file_get_size(aptr->body->filename);
318  }
319  else
320  l = aptr->body->length;
321 
322  if (!optional)
323  {
324  char tmp[128];
325  mutt_str_pretty_size(tmp, sizeof(tmp), l);
326  mutt_format_s(buf, buflen, prec, tmp);
327  }
328  else if (l == 0)
329  optional = false;
330 
331  break;
332  }
333  case 't':
334  if (!optional)
335  snprintf(buf, buflen, "%c", aptr->body->tagged ? '*' : ' ');
336  else if (!aptr->body->tagged)
337  optional = false;
338  break;
339  case 'T':
340  if (!optional)
341  mutt_format_s_tree(buf, buflen, prec, NONULL(aptr->tree));
342  else if (!aptr->tree)
343  optional = false;
344  break;
345  case 'u':
346  if (!optional)
347  snprintf(buf, buflen, "%c", aptr->body->unlink ? '-' : ' ');
348  else if (!aptr->body->unlink)
349  optional = false;
350  break;
351  case 'X':
352  if (optional)
353  optional = ((aptr->body->attach_count + aptr->body->attach_qualifies) != 0);
354  else
355  {
356  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
357  snprintf(buf, buflen, fmt, aptr->body->attach_count + aptr->body->attach_qualifies);
358  }
359  break;
360  default:
361  *buf = '\0';
362  }
363 
364  if (optional)
365  {
366  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data,
368  }
369  else if (flags & MUTT_FORMAT_OPTIONAL)
370  {
371  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str,
373  }
374 
375  /* We return the format string, unchanged */
376  return src;
377 }
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:310
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string with tree characters.
Definition: curs_lib.c:802
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body's character set.
Definition: body.c:131
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1551
#define MUTT_FORMAT_FORCESUBJ
Print the subject even if unchanged.
Definition: format_flags.h:31
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
#define MUTT_FORMAT_STAT_FILE
Used by attach_format_str.
Definition: format_flags.h:34
const char * attach_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the attachment menu - Implements format_t -.
Definition: dlg_attach.c:150
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1405
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
@ TYPE_TEXT
Type: 'text/*'.
Definition: mime.h:38
#define ENCODING(x)
Definition: mime.h:92
#define TYPE(body)
Definition: mime.h:89
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:599
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1673
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:433
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1442
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
An email to which things will be attached.
Definition: attach.h:35
struct Body * body
Attachment.
Definition: attach.h:36
char * tree
Tree characters to display.
Definition: attach.h:39
int num
Attachment index number.
Definition: attach.h:41
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition: body.h:56
signed short attach_count
Number of attachments.
Definition: body.h:90
bool deleted
Attachment marked for deletion.
Definition: body.h:87
bool noconv
Don't do character set conversion.
Definition: body.h:46
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:67
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
struct Email * email
header information for message/rfc822
Definition: body.h:73
char * description
content-description
Definition: body.h:55
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:42
bool attach_qualifies
This attachment should be counted.
Definition: body.h:86
bool tagged
This attachment is tagged.
Definition: body.h:89
char * subtype
content-type subtype
Definition: body.h:60
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:41
unsigned int type
content-type primary type, ContentType
Definition: body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition: body.h:58
String manipulation buffer.
Definition: buffer.h:34
char * data
Pointer to data.
Definition: buffer.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ autocrypt_format_str()

static const char* autocrypt_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the Autocrypt account list - Implements format_t -.

Expando Description
%a Email address
%k Gpg keyid
%n Current entry number
%p Prefer-encrypt flag
%s Status flag (active/inactive)

Definition at line 124 of file dlg_autocrypt.c.

128 {
129  struct AccountEntry *entry = (struct AccountEntry *) data;
130  char tmp[128];
131 
132  switch (op)
133  {
134  case 'a':
135  mutt_format_s(buf, buflen, prec, entry->addr->mailbox);
136  break;
137  case 'k':
138  mutt_format_s(buf, buflen, prec, entry->account->keyid);
139  break;
140  case 'n':
141  snprintf(tmp, sizeof(tmp), "%%%sd", prec);
142  snprintf(buf, buflen, tmp, entry->num);
143  break;
144  case 'p':
145  if (entry->account->prefer_encrypt)
146  {
147  /* L10N: Autocrypt Account menu.
148  flag that an account has prefer-encrypt set */
149  mutt_format_s(buf, buflen, prec, _("prefer encrypt"));
150  }
151  else
152  {
153  /* L10N: Autocrypt Account menu.
154  flag that an account has prefer-encrypt unset;
155  thus encryption will need to be manually enabled. */
156  mutt_format_s(buf, buflen, prec, _("manual encrypt"));
157  }
158  break;
159  case 's':
160  if (entry->account->enabled)
161  {
162  /* L10N: Autocrypt Account menu.
163  flag that an account is enabled/active */
164  mutt_format_s(buf, buflen, prec, _("active"));
165  }
166  else
167  {
168  /* L10N: Autocrypt Account menu.
169  flag that an account is disabled/inactive */
170  mutt_format_s(buf, buflen, prec, _("inactive"));
171  }
172  break;
173  }
174 
175  return (src);
176 }
#define _(a)
Definition: message.h:28
An entry in the Autocrypt account Menu.
Definition: private.h:44
struct Address * addr
Email address associated with the account.
Definition: private.h:47
struct AutocryptAccount * account
Account details.
Definition: private.h:46
int num
Number in the index.
Definition: private.h:45
char * mailbox
Mailbox and host address.
Definition: address.h:38
char * keyid
PGP Key id.
Definition: lib.h:108
bool enabled
Is this account enabled.
Definition: lib.h:111
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:110
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ folder_format_str()

static const char* folder_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the folder browser - Implements format_t -.

Expando Description
%C Current file number
%d Date/time folder was last modified
%D Date/time folder was last modified using $date_format.
%F File permissions
%f Filename (with suffix /, @ or *)
%g Group name (or numeric gid, if missing)
%i Description of the folder
%l Number of hard links
%m Number of messages in the mailbox
%N "N" if mailbox has new mail, " " (space) otherwise
%n Number of unread messages in the mailbox
%s Size in bytes
%t * if the file is tagged, blank otherwise
%u Owner name (or numeric uid, if missing)

Definition at line 207 of file browser.c.

211 {
212  char fn[128], fmt[128];
213  struct Folder *folder = (struct Folder *) data;
214  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
215 
216  switch (op)
217  {
218  case 'C':
219  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
220  snprintf(buf, buflen, fmt, folder->num + 1);
221  break;
222 
223  case 'd':
224  case 'D':
225  if (folder->ff->local)
226  {
227  bool do_locales = true;
228 
229  const char *t_fmt = NULL;
230  if (op == 'D')
231  {
232  const char *const c_date_format = cs_subset_string(NeoMutt->sub, "date_format");
233  t_fmt = NONULL(c_date_format);
234  if (*t_fmt == '!')
235  {
236  t_fmt++;
237  do_locales = false;
238  }
239  }
240  else
241  {
242  static const time_t one_year = 31536000;
243  t_fmt = ((mutt_date_epoch() - folder->ff->mtime) < one_year) ? "%b %d %H:%M" : "%b %d %Y";
244  }
245 
246  if (!do_locales)
247  setlocale(LC_TIME, "C");
248  char date[128];
249  mutt_date_localtime_format(date, sizeof(date), t_fmt, folder->ff->mtime);
250  if (!do_locales)
251  setlocale(LC_TIME, "");
252 
253  mutt_format_s(buf, buflen, prec, date);
254  }
255  else
256  {
257  mutt_format_s(buf, buflen, prec, "");
258  }
259  break;
260 
261  case 'f':
262  {
263  char *s = NULL;
264 
265  s = NONULL(folder->ff->name);
266 
267  snprintf(fn, sizeof(fn), "%s%s", s,
268  folder->ff->local ?
269  (S_ISLNK(folder->ff->mode) ?
270  "@" :
271  (S_ISDIR(folder->ff->mode) ?
272  "/" :
273  (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
274  "");
275 
276  mutt_format_s(buf, buflen, prec, fn);
277  break;
278  }
279  case 'F':
280  {
281  if (folder->ff->local)
282  {
283  char permission[11];
284  snprintf(permission, sizeof(permission), "%c%c%c%c%c%c%c%c%c%c",
285  S_ISDIR(folder->ff->mode) ? 'd' : (S_ISLNK(folder->ff->mode) ? 'l' : '-'),
286  ((folder->ff->mode & S_IRUSR) != 0) ? 'r' : '-',
287  ((folder->ff->mode & S_IWUSR) != 0) ? 'w' : '-',
288  ((folder->ff->mode & S_ISUID) != 0) ? 's' :
289  ((folder->ff->mode & S_IXUSR) != 0) ? 'x' :
290  '-',
291  ((folder->ff->mode & S_IRGRP) != 0) ? 'r' : '-',
292  ((folder->ff->mode & S_IWGRP) != 0) ? 'w' : '-',
293  ((folder->ff->mode & S_ISGID) != 0) ? 's' :
294  ((folder->ff->mode & S_IXGRP) != 0) ? 'x' :
295  '-',
296  ((folder->ff->mode & S_IROTH) != 0) ? 'r' : '-',
297  ((folder->ff->mode & S_IWOTH) != 0) ? 'w' : '-',
298  ((folder->ff->mode & S_ISVTX) != 0) ? 't' :
299  ((folder->ff->mode & S_IXOTH) != 0) ? 'x' :
300  '-');
301  mutt_format_s(buf, buflen, prec, permission);
302  }
303 #ifdef USE_IMAP
304  else if (folder->ff->imap)
305  {
306  char permission[11];
307  /* mark folders with subfolders AND mail */
308  snprintf(permission, sizeof(permission), "IMAP %c",
309  (folder->ff->inferiors && folder->ff->selectable) ? '+' : ' ');
310  mutt_format_s(buf, buflen, prec, permission);
311  }
312 #endif
313  else
314  mutt_format_s(buf, buflen, prec, "");
315  break;
316  }
317 
318  case 'g':
319  if (folder->ff->local)
320  {
321  struct group *gr = getgrgid(folder->ff->gid);
322  if (gr)
323  {
324  mutt_format_s(buf, buflen, prec, gr->gr_name);
325  }
326  else
327  {
328  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
329  snprintf(buf, buflen, fmt, folder->ff->gid);
330  }
331  }
332  else
333  {
334  mutt_format_s(buf, buflen, prec, "");
335  }
336  break;
337 
338  case 'i':
339  {
340  char *s = NULL;
341  if (folder->ff->desc)
342  s = folder->ff->desc;
343  else
344  s = folder->ff->name;
345 
346  snprintf(fn, sizeof(fn), "%s%s", s,
347  folder->ff->local ?
348  (S_ISLNK(folder->ff->mode) ?
349  "@" :
350  (S_ISDIR(folder->ff->mode) ?
351  "/" :
352  (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
353  "");
354 
355  mutt_format_s(buf, buflen, prec, fn);
356  break;
357  }
358 
359  case 'l':
360  if (folder->ff->local)
361  {
362  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
363  snprintf(buf, buflen, fmt, folder->ff->nlink);
364  }
365  else
366  {
367  mutt_format_s(buf, buflen, prec, "");
368  }
369  break;
370 
371  case 'm':
372  if (!optional)
373  {
374  if (folder->ff->has_mailbox)
375  {
376  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
377  snprintf(buf, buflen, fmt, folder->ff->msg_count);
378  }
379  else
380  {
381  mutt_format_s(buf, buflen, prec, "");
382  }
383  }
384  else if (folder->ff->msg_count == 0)
385  optional = false;
386  break;
387 
388  case 'N':
389  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
390  snprintf(buf, buflen, fmt, folder->ff->has_new_mail ? 'N' : ' ');
391  break;
392 
393  case 'n':
394  if (!optional)
395  {
396  if (folder->ff->has_mailbox)
397  {
398  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
399  snprintf(buf, buflen, fmt, folder->ff->msg_unread);
400  }
401  else
402  {
403  mutt_format_s(buf, buflen, prec, "");
404  }
405  }
406  else if (folder->ff->msg_unread == 0)
407  optional = false;
408  break;
409 
410  case 's':
411  if (folder->ff->local)
412  {
413  mutt_str_pretty_size(fn, sizeof(fn), folder->ff->size);
414  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
415  snprintf(buf, buflen, fmt, fn);
416  }
417  else
418  {
419  mutt_format_s(buf, buflen, prec, "");
420  }
421  break;
422 
423  case 't':
424  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
425  snprintf(buf, buflen, fmt, folder->ff->tagged ? '*' : ' ');
426  break;
427 
428  case 'u':
429  if (folder->ff->local)
430  {
431  struct passwd *pw = getpwuid(folder->ff->uid);
432  if (pw)
433  {
434  mutt_format_s(buf, buflen, prec, pw->pw_name);
435  }
436  else
437  {
438  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
439  snprintf(buf, buflen, fmt, folder->ff->uid);
440  }
441  }
442  else
443  {
444  mutt_format_s(buf, buflen, prec, "");
445  }
446  break;
447 
448  default:
449  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
450  snprintf(buf, buflen, fmt, op);
451  break;
452  }
453 
454  if (optional)
455  {
456  mutt_expando_format(buf, buflen, col, cols, if_str, folder_format_str, data,
458  }
459  else if (flags & MUTT_FORMAT_OPTIONAL)
460  {
461  mutt_expando_format(buf, buflen, col, cols, else_str, folder_format_str,
462  data, MUTT_FORMAT_NO_FLAGS);
463  }
464 
465  /* We return the format string, unchanged */
466  return src;
467 }
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:691
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
static const char * folder_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the folder browser - Implements format_t -.
Definition: browser.c:207
bool selectable
Folder can be selected.
Definition: lib.h:92
bool imap
This is an IMAP folder.
Definition: lib.h:91
bool has_mailbox
This is a mailbox.
Definition: lib.h:95
char * name
Name of file/dir/mailbox.
Definition: lib.h:81
uid_t uid
File's User ID.
Definition: lib.h:77
bool tagged
Folder is tagged.
Definition: lib.h:97
gid_t gid
File's Group ID.
Definition: lib.h:78
bool has_new_mail
true if mailbox has "new mail"
Definition: lib.h:84
nlink_t nlink
Number of hard links.
Definition: lib.h:79
char * desc
Description of mailbox.
Definition: lib.h:82
off_t size
File size.
Definition: lib.h:75
time_t mtime
Modification time.
Definition: lib.h:76
int msg_count
total number of messages
Definition: lib.h:85
mode_t mode
File permissions.
Definition: lib.h:74
bool inferiors
Folder has children.
Definition: lib.h:93
int msg_unread
number of unread messages
Definition: lib.h:86
A folder/dir in the browser.
Definition: lib.h:64
int num
Number in the index.
Definition: lib.h:66
struct FolderFile * ff
File / Dir / Mailbox.
Definition: lib.h:65
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compress_format_str()

static const char* compress_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Expand the filenames in a command string - Implements format_t -.

Expando Description
%f Compressed file
%t Plaintext, temporary file

Definition at line 250 of file compress.c.

254 {
255  if (!buf || (data == 0))
256  return src;
257 
258  struct Mailbox *m = (struct Mailbox *) data;
259 
260  /* NOTE the compressed file config vars expect %f and %t to be
261  * surrounded by '' (unlike other NeoMutt config vars, which add the
262  * outer quotes for the user). This is why we use the
263  * mutt_buffer_quote_filename() form with add_outer of false. */
264  struct Buffer *quoted = mutt_buffer_pool_get();
265  switch (op)
266  {
267  case 'f':
268  /* Compressed file */
269  mutt_buffer_quote_filename(quoted, m->realpath, false);
270  snprintf(buf, buflen, "%s", mutt_buffer_string(quoted));
271  break;
272  case 't':
273  /* Plaintext, temporary file */
274  mutt_buffer_quote_filename(quoted, mailbox_path(m), false);
275  snprintf(buf, buflen, "%s", mutt_buffer_string(quoted));
276  break;
277  }
278 
279  mutt_buffer_pool_release(&quoted);
280  return src;
281 }
void mutt_buffer_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell's quoting rules.
Definition: file.c:891
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:211
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compose_format_str()

static const char* compose_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Create the status bar string for compose mode - Implements format_t -.

Expando Description
%a Total number of attachments
%h Local hostname
%l Approximate size (in bytes) of the current message
%v NeoMutt version string

Definition at line 103 of file cbar.c.

107 {
108  char fmt[128], tmp[128];
109  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
110  struct ComposeSharedData *shared = (struct ComposeSharedData *) data;
111 
112  *buf = '\0';
113  switch (op)
114  {
115  case 'a': /* total number of attachments */
116  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
117  snprintf(buf, buflen, fmt, num_attachments(shared->adata));
118  break;
119 
120  case 'h': /* hostname */
121  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
122  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
123  break;
124 
125  case 'l': /* approx length of current message in bytes */
126  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
127  mutt_str_pretty_size(tmp, sizeof(tmp),
128  cum_attachs_size(shared->sub, shared->adata));
129  snprintf(buf, buflen, fmt, tmp);
130  break;
131 
132  case 'v':
133  snprintf(buf, buflen, "%s", mutt_make_version());
134  break;
135 
136  case 0:
137  *buf = '\0';
138  return src;
139 
140  default:
141  snprintf(buf, buflen, "%%%s%c", prec, op);
142  break;
143  }
144 
145  if (optional)
146  {
147  mutt_expando_format(buf, buflen, col, cols, if_str, compose_format_str, data, flags);
148  }
149  // This format function doesn't have any optional expandos,
150  // so there's no `else if (flags & MUTT_FORMAT_OPTIONAL)` clause
151 
152  return src;
153 }
int num_attachments(struct ComposeAttachData *adata)
Count the number of attachments.
Definition: cbar.c:86
unsigned long cum_attachs_size(struct ConfigSubset *sub, struct ComposeAttachData *adata)
Cumulative Attachments Size.
Definition: attach.c:85
static const char * compose_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Create the status bar string for compose mode - Implements format_t -.
Definition: cbar.c:103
char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:50
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1470
Shared Compose Data.
Definition: shared_data.h:33
struct ConfigSubset * sub
Config set to use.
Definition: shared_data.h:34
int flags
Flags, e.g. MUTT_COMPOSE_NOFREEHEADER.
Definition: shared_data.h:41
struct ComposeAttachData * adata
Attachments.
Definition: shared_data.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ index_format_str()

static const char* index_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the index list - Implements format_t -.

Expando Description
%a Address of the author
%A Reply-to address (if present; otherwise: address of author)
%b Filename of the original message folder (think mailbox)
%B The list to which the email was sent, or else the folder name (b)
%C Current message number
%c Number of characters (bytes) in the body of the message
%cr Number of characters (bytes) in the message, including header
%D Date and time of message using $date_format and local timezone
%d Date and time of message using $date_format and sender's timezone
%e Current message number in thread
%E Number of messages in current thread
%Fp Like F, but plain. No contextual formatting is applied to recipient name
%F Author name, or recipient name if the message is from you
%f Sender (address + real name), either From: or Return-Path:
%Gx Individual message tag (e.g. notmuch tags/imap flags)
%g Message tags (e.g. notmuch tags/imap flags)
%H Spam attribute(s) of this message
%I Initials of author
%i Message-id of the current message
%J Message tags (if present, tree unfolded, and != parent's tags)
%K The list to which the email was sent (if any; otherwise: empty)
%L Like F, except 'lists' are displayed first
%l Number of lines in the message
%M Number of hidden messages if the thread is collapsed
%m Total number of message in the mailbox
%n Author's real name (or address if missing)
%N Message score
%O Like L, except using address instead of name
%P Progress indicator for the built-in pager (how much of the file has been displayed)
%q Newsgroup name (if compiled with NNTP support)
%R Comma separated list of Cc: recipients
%r Comma separated list of To: recipients
%S Single character status of the message (N/O/D/d/!/r/-)
%s Subject of the message
%t 'To:' field (recipients)
%T The appropriate character from the $to_chars string
%u User (login) name of the author
%v First name of the author, or the recipient if the message is from you
%W Name of organization of author ('Organization:' field)
%x 'X-Comment-To:' field (if present and compiled with NNTP support)
%X Number of MIME attachments
%y 'X-Label:' field (if present)
%Y 'X-Label:' field (if present, tree unfolded, and != parent's x-label)
%zc Message crypto flags
%zs Message status flags
%zt Message tag flags
%Z Combined message flags
%@name@ Insert and evaluate format-string from the matching "$index-format-hook" command
%(fmt) Date/time when the message was received
%[fmt] Message date/time converted to the local time zone
%{fmt} Message date/time converted to sender's time zone

Definition at line 439 of file hdrline.c.

443 {
444  struct HdrFormatInfo *hfi = (struct HdrFormatInfo *) data;
445  char fmt[128], tmp[1024];
446  char *p = NULL, *tags = NULL;
447  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
448  const bool threads = mutt_using_threads();
449  int is_index = (flags & MUTT_FORMAT_INDEX);
450  size_t colorlen;
451 
452  struct Email *e = hfi->email;
453  size_t msg_in_pager = hfi->msg_in_pager;
454  struct Mailbox *m = hfi->mailbox;
455 
456  if (!e || !e->env)
457  return src;
458 
459  const struct Address *reply_to = TAILQ_FIRST(&e->env->reply_to);
460  const struct Address *from = TAILQ_FIRST(&e->env->from);
461  const struct Address *to = TAILQ_FIRST(&e->env->to);
462  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
463 
464  const struct MbTable *c_crypt_chars = cs_subset_mbtable(NeoMutt->sub, "crypt_chars");
465  const struct MbTable *c_flag_chars = cs_subset_mbtable(NeoMutt->sub, "flag_chars");
466  const struct MbTable *c_to_chars = cs_subset_mbtable(NeoMutt->sub, "to_chars");
467  const char *const c_date_format = cs_subset_string(NeoMutt->sub, "date_format");
468 
469  buf[0] = '\0';
470  switch (op)
471  {
472  case 'A':
473  case 'I':
474  if (op == 'A')
475  {
476  if (reply_to && reply_to->mailbox)
477  {
478  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
479  mutt_format_s(buf + colorlen, buflen - colorlen, prec,
480  mutt_addr_for_display(reply_to));
481  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
482  break;
483  }
484  }
485  else
486  {
487  if (mutt_mb_get_initials(mutt_get_name(from), tmp, sizeof(tmp)))
488  {
489  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
490  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
491  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
492  break;
493  }
494  }
495  /* fallthrough */
496 
497  case 'a':
498  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
499  if (from && from->mailbox)
500  {
501  mutt_format_s(buf + colorlen, buflen - colorlen, prec, mutt_addr_for_display(from));
502  }
503  else
504  mutt_format_s(buf + colorlen, buflen - colorlen, prec, "");
505  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
506  break;
507 
508  case 'B':
509  case 'K':
510  if (first_mailing_list(buf, buflen, &e->env->to) ||
511  first_mailing_list(buf, buflen, &e->env->cc))
512  {
513  mutt_str_copy(tmp, buf, sizeof(tmp));
514  mutt_format_s(buf, buflen, prec, tmp);
515  }
516  else if (optional)
517  {
518  optional = false;
519  }
520  break;
521 
522  case 'b':
523  if (m)
524  {
525  p = strrchr(mailbox_path(m), '/');
526 #ifdef USE_NOTMUCH
527  if (m->type == MUTT_NOTMUCH)
528  {
529  char *rel_path = nm_email_get_folder_rel_db(m, e);
530  if (rel_path)
531  p = rel_path;
532  }
533 #endif
534 
535  if (p)
536  mutt_str_copy(buf, p + 1, buflen);
537  else
538  mutt_str_copy(buf, mailbox_path(m), buflen);
539  }
540  else
541  mutt_str_copy(buf, "(null)", buflen);
542  mutt_str_copy(tmp, buf, sizeof(tmp));
543  mutt_format_s(buf, buflen, prec, tmp);
544  break;
545 
546  case 'c':
547  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SIZE);
548  if (src[0] == 'r')
549  {
550  mutt_str_pretty_size(tmp, sizeof(tmp), email_size(e));
551  src++;
552  }
553  else
554  {
555  mutt_str_pretty_size(tmp, sizeof(tmp), e->body->length);
556  }
557  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
558  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
559  break;
560 
561  case 'C':
562  colorlen = add_index_color(fmt, sizeof(fmt), flags, MT_COLOR_INDEX_NUMBER);
563  snprintf(fmt + colorlen, sizeof(fmt) - colorlen, "%%%sd", prec);
564  add_index_color(fmt + colorlen, sizeof(fmt) - colorlen, flags, MT_COLOR_INDEX);
565  snprintf(buf, buflen, fmt, e->msgno + 1);
566  break;
567 
568  case 'd':
569  case 'D':
570  case '{':
571  case '[':
572  case '(':
573  case '<':
574  /* preprocess $date_format to handle %Z */
575  {
576  const char *cp = NULL;
577  time_t now;
578  int j = 0;
579 
580  if (optional && ((op == '[') || (op == '(')))
581  {
582  now = mutt_date_epoch();
583  struct tm tm = mutt_date_localtime(now);
584  now -= (op == '(') ? e->received : e->date_sent;
585 
586  char *is = (char *) prec;
587  bool invert = false;
588  if (*is == '>')
589  {
590  invert = true;
591  is++;
592  }
593 
594  while (*is && (*is != '?'))
595  {
596  int t = strtol(is, &is, 10);
597  /* semi-broken (assuming 30 days in all months) */
598  switch (*(is++))
599  {
600  case 'y':
601  if (t > 1)
602  {
603  t--;
604  t *= (60 * 60 * 24 * 365);
605  }
606  t += ((tm.tm_mon * 60 * 60 * 24 * 30) + (tm.tm_mday * 60 * 60 * 24) +
607  (tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec);
608  break;
609 
610  case 'm':
611  if (t > 1)
612  {
613  t--;
614  t *= (60 * 60 * 24 * 30);
615  }
616  t += ((tm.tm_mday * 60 * 60 * 24) + (tm.tm_hour * 60 * 60) +
617  (tm.tm_min * 60) + tm.tm_sec);
618  break;
619 
620  case 'w':
621  if (t > 1)
622  {
623  t--;
624  t *= (60 * 60 * 24 * 7);
625  }
626  t += ((tm.tm_wday * 60 * 60 * 24) + (tm.tm_hour * 60 * 60) +
627  (tm.tm_min * 60) + tm.tm_sec);
628  break;
629 
630  case 'd':
631  if (t > 1)
632  {
633  t--;
634  t *= (60 * 60 * 24);
635  }
636  t += ((tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec);
637  break;
638 
639  case 'H':
640  if (t > 1)
641  {
642  t--;
643  t *= (60 * 60);
644  }
645  t += ((tm.tm_min * 60) + tm.tm_sec);
646  break;
647 
648  case 'M':
649  if (t > 1)
650  {
651  t--;
652  t *= (60);
653  }
654  t += (tm.tm_sec);
655  break;
656 
657  default:
658  break;
659  }
660  j += t;
661  }
662 
663  if (j < 0)
664  j *= -1;
665 
666  if (((now > j) || (now < (-1 * j))) ^ invert)
667  optional = false;
668  break;
669  }
670 
671  p = buf;
672 
673  cp = ((op == 'd') || (op == 'D')) ? (NONULL(c_date_format)) : src;
674  bool do_locales;
675  if (*cp == '!')
676  {
677  do_locales = false;
678  cp++;
679  }
680  else
681  do_locales = true;
682 
683  size_t len = buflen - 1;
684  while ((len > 0) &&
685  ((((op == 'd') || (op == 'D')) && *cp) ||
686  ((op == '{') && (*cp != '}')) || ((op == '[') && (*cp != ']')) ||
687  ((op == '(') && (*cp != ')')) || ((op == '<') && (*cp != '>'))))
688  {
689  if (*cp == '%')
690  {
691  cp++;
692  if (((*cp == 'Z') || (*cp == 'z')) && ((op == 'd') || (op == '{')))
693  {
694  if (len >= 5)
695  {
696  sprintf(p, "%c%02u%02u", e->zoccident ? '-' : '+', e->zhours, e->zminutes);
697  p += 5;
698  len -= 5;
699  }
700  else
701  break; /* not enough space left */
702  }
703  else
704  {
705  if (len >= 2)
706  {
707  *p++ = '%';
708  *p++ = *cp;
709  len -= 2;
710  }
711  else
712  break; /* not enough space */
713  }
714  cp++;
715  }
716  else
717  {
718  *p++ = *cp++;
719  len--;
720  }
721  }
722  *p = '\0';
723 
724  struct tm tm;
725  if ((op == '[') || (op == 'D'))
727  else if (op == '(')
728  tm = mutt_date_localtime(e->received);
729  else if (op == '<')
730  {
732  }
733  else
734  {
735  /* restore sender's time zone */
736  now = e->date_sent;
737  if (e->zoccident)
738  now -= (e->zhours * 3600 + e->zminutes * 60);
739  else
740  now += (e->zhours * 3600 + e->zminutes * 60);
741  tm = mutt_date_gmtime(now);
742  }
743 
744  if (!do_locales)
745  setlocale(LC_TIME, "C");
746  strftime(tmp, sizeof(tmp), buf, &tm);
747  if (!do_locales)
748  setlocale(LC_TIME, "");
749 
750  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_DATE);
751  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
752  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
753 
754  if ((len > 0) && (op != 'd') && (op != 'D')) /* Skip ending op */
755  src = cp + 1;
756  break;
757  }
758 
759  case 'e':
760  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
761  snprintf(buf, buflen, fmt, mutt_messages_in_thread(m, e, MIT_POSITION));
762  break;
763 
764  case 'E':
765  if (!optional)
766  {
767  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
768  snprintf(buf, buflen, fmt, mutt_messages_in_thread(m, e, MIT_NUM_MESSAGES));
769  }
770  else if (mutt_messages_in_thread(m, e, MIT_NUM_MESSAGES) <= 1)
771  optional = false;
772  break;
773 
774  case 'f':
775  tmp[0] = '\0';
776  mutt_addrlist_write(&e->env->from, tmp, sizeof(tmp), true);
777  mutt_format_s(buf, buflen, prec, tmp);
778  break;
779 
780  case 'F':
781  if (!optional)
782  {
783  const bool is_plain = (src[0] == 'p');
784  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
785  make_from(e->env, tmp, sizeof(tmp), false,
786  (is_plain ? MUTT_FORMAT_PLAIN : MUTT_FORMAT_NO_FLAGS));
787  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
788  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
789 
790  if (is_plain)
791  src++;
792  }
793  else if (mutt_addr_is_user(from))
794  {
795  optional = false;
796  }
797  break;
798 
799  case 'g':
800  tags = driver_tags_get_transformed(&e->tags);
801  if (!optional)
802  {
803  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_TAGS);
804  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(tags));
805  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
806  }
807  else if (!tags)
808  optional = false;
809  FREE(&tags);
810  break;
811 
812  case 'G':
813  {
814  char format[3];
815  char *tag = NULL;
816 
817  if (!optional)
818  {
819  format[0] = op;
820  format[1] = *src;
821  format[2] = '\0';
822 
823  tag = mutt_hash_find(TagFormats, format);
824  if (tag)
825  {
826  tags = driver_tags_get_transformed_for(&e->tags, tag);
827  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_TAG);
828  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(tags));
829  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
830  FREE(&tags);
831  }
832  src++;
833  }
834  else
835  {
836  format[0] = op;
837  format[1] = *prec;
838  format[2] = '\0';
839 
840  tag = mutt_hash_find(TagFormats, format);
841  if (tag)
842  {
843  tags = driver_tags_get_transformed_for(&e->tags, tag);
844  if (!tags)
845  optional = false;
846  FREE(&tags);
847  }
848  }
849  break;
850  }
851 
852  case 'H':
853  /* (Hormel) spam score */
854  if (optional)
855  optional = !mutt_buffer_is_empty(&e->env->spam);
856 
857  mutt_format_s(buf, buflen, prec, mutt_buffer_string(&e->env->spam));
858  break;
859 
860  case 'i':
861  mutt_format_s(buf, buflen, prec, e->env->message_id ? e->env->message_id : "<no.id>");
862  break;
863 
864  case 'J':
865  {
866  bool have_tags = true;
867  tags = driver_tags_get_transformed(&e->tags);
868  if (tags)
869  {
870  if (flags & MUTT_FORMAT_TREE)
871  {
872  char *parent_tags = NULL;
873  if (e->thread->prev && e->thread->prev->message)
874  {
875  parent_tags = driver_tags_get_transformed(&e->thread->prev->message->tags);
876  }
877  if (!parent_tags && e->thread->parent && e->thread->parent->message)
878  {
879  parent_tags = driver_tags_get_transformed(
880  &e->thread->parent->message->tags);
881  }
882  if (parent_tags && mutt_istr_equal(tags, parent_tags))
883  have_tags = false;
884  FREE(&parent_tags);
885  }
886  }
887  else
888  have_tags = false;
889 
890  if (optional)
891  optional = have_tags;
892 
893  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_TAGS);
894  if (have_tags)
895  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tags);
896  else
897  mutt_format_s(buf + colorlen, buflen - colorlen, prec, "");
898  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
899  FREE(&tags);
900  break;
901  }
902 
903  case 'l':
904  if (!optional)
905  {
906  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
907  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SIZE);
908  snprintf(buf + colorlen, buflen - colorlen, fmt, (int) e->lines);
909  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
910  }
911  else if (e->lines <= 0)
912  optional = false;
913  break;
914 
915  case 'L':
916  if (!optional)
917  {
918  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
919  make_from(e->env, tmp, sizeof(tmp), true, flags);
920  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
921  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
922  }
923  else if (!check_for_mailing_list(&e->env->to, NULL, NULL, 0) &&
924  !check_for_mailing_list(&e->env->cc, NULL, NULL, 0))
925  {
926  optional = false;
927  }
928  break;
929 
930  case 'm':
931  if (m)
932  {
933  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
934  snprintf(buf, buflen, fmt, m->msg_count);
935  }
936  else
937  mutt_str_copy(buf, "(null)", buflen);
938  break;
939 
940  case 'n':
941  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
942  mutt_format_s(buf + colorlen, buflen - colorlen, prec, mutt_get_name(from));
943  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
944  break;
945 
946  case 'M':
947  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
948  if (!optional)
949  {
950  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_COLLAPSED);
951  if (threads && is_index && e->collapsed && (e->num_hidden > 1))
952  {
953  snprintf(buf + colorlen, buflen - colorlen, fmt, e->num_hidden);
954  add_index_color(buf, buflen - colorlen, flags, MT_COLOR_INDEX);
955  }
956  else if (is_index && threads)
957  {
958  mutt_format_s(buf + colorlen, buflen - colorlen, prec, " ");
959  add_index_color(buf, buflen - colorlen, flags, MT_COLOR_INDEX);
960  }
961  else
962  *buf = '\0';
963  }
964  else
965  {
966  if (!(threads && is_index && e->collapsed && (e->num_hidden > 1)))
967  optional = false;
968  }
969  break;
970 
971  case 'N':
972  if (!optional)
973  {
974  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
975  snprintf(buf, buflen, fmt, e->score);
976  }
977  else
978  {
979  if (e->score == 0)
980  optional = false;
981  }
982  break;
983 
984  case 'O':
985  if (!optional)
986  {
987  make_from_addr(e->env, tmp, sizeof(tmp), true);
988  const bool c_save_address = cs_subset_bool(NeoMutt->sub, "save_address");
989  if (!c_save_address && (p = strpbrk(tmp, "%@")))
990  *p = '\0';
991  mutt_format_s(buf, buflen, prec, tmp);
992  }
993  else if (!check_for_mailing_list_addr(&e->env->to, NULL, 0) &&
994  !check_for_mailing_list_addr(&e->env->cc, NULL, 0))
995  {
996  optional = false;
997  }
998  break;
999 
1000  case 'P':
1001  mutt_str_copy(buf, hfi->pager_progress, buflen);
1002  break;
1003 
1004 #ifdef USE_NNTP
1005  case 'q':
1006  mutt_format_s(buf, buflen, prec, e->env->newsgroups ? e->env->newsgroups : "");
1007  break;
1008 #endif
1009 
1010  case 'r':
1011  tmp[0] = '\0';
1012  mutt_addrlist_write(&e->env->to, tmp, sizeof(tmp), true);
1013  if (optional && (tmp[0] == '\0'))
1014  optional = false;
1015  mutt_format_s(buf, buflen, prec, tmp);
1016  break;
1017 
1018  case 'R':
1019  tmp[0] = '\0';
1020  mutt_addrlist_write(&e->env->cc, tmp, sizeof(tmp), true);
1021  if (optional && (tmp[0] == '\0'))
1022  optional = false;
1023  mutt_format_s(buf, buflen, prec, tmp);
1024  break;
1025 
1026  case 's':
1027  {
1028  subjrx_apply_mods(e->env);
1029  char *subj = NULL;
1030  if (e->env->disp_subj)
1031  subj = e->env->disp_subj;
1032  else
1033  subj = e->env->subject;
1034  if (flags & MUTT_FORMAT_TREE && !e->collapsed)
1035  {
1036  if (flags & MUTT_FORMAT_FORCESUBJ)
1037  {
1038  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SUBJECT);
1039  mutt_format_s(buf + colorlen, buflen - colorlen, "", NONULL(subj));
1040  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1041  snprintf(tmp, sizeof(tmp), "%s%s", e->tree, buf);
1042  mutt_format_s_tree(buf, buflen, prec, tmp);
1043  }
1044  else
1045  mutt_format_s_tree(buf, buflen, prec, e->tree);
1046  }
1047  else
1048  {
1049  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SUBJECT);
1050  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(subj));
1051  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1052  }
1053  break;
1054  }
1055 
1056  case 'S':
1057  {
1058  const char *wch = NULL;
1059  if (e->deleted)
1060  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_DELETED);
1061  else if (e->attach_del)
1062  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_DELETED_ATTACH);
1063  else if (e->tagged)
1064  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_TAGGED);
1065  else if (e->flagged)
1066  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_IMPORTANT);
1067  else if (e->replied)
1068  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_REPLIED);
1069  else if (e->read && (msg_in_pager != e->msgno))
1070  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_SEMPTY);
1071  else if (e->old)
1072  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_OLD);
1073  else
1074  wch = get_nth_wchar(c_flag_chars, FLAG_CHAR_NEW);
1075 
1076  snprintf(tmp, sizeof(tmp), "%s", wch);
1077  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_FLAGS);
1078  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
1079  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1080  break;
1081  }
1082 
1083  case 't':
1084  tmp[0] = '\0';
1085  if (!check_for_mailing_list(&e->env->to, "To ", tmp, sizeof(tmp)) &&
1086  !check_for_mailing_list(&e->env->cc, "Cc ", tmp, sizeof(tmp)))
1087  {
1088  if (to)
1089  snprintf(tmp, sizeof(tmp), "To %s", mutt_get_name(to));
1090  else if (cc)
1091  snprintf(tmp, sizeof(tmp), "Cc %s", mutt_get_name(cc));
1092  }
1093  mutt_format_s(buf, buflen, prec, tmp);
1094  break;
1095 
1096  case 'T':
1097  {
1098  int i;
1099  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1100  snprintf(buf, buflen, fmt,
1101  (c_to_chars && ((i = user_is_recipient(e))) < c_to_chars->len) ?
1102  c_to_chars->chars[i] :
1103  " ");
1104  break;
1105  }
1106 
1107  case 'u':
1108  if (from && from->mailbox)
1109  {
1110  mutt_str_copy(tmp, mutt_addr_for_display(from), sizeof(tmp));
1111  p = strpbrk(tmp, "%@");
1112  if (p)
1113  *p = '\0';
1114  }
1115  else
1116  tmp[0] = '\0';
1117  mutt_format_s(buf, buflen, prec, tmp);
1118  break;
1119 
1120  case 'v':
1121  if (mutt_addr_is_user(from))
1122  {
1123  if (to)
1124  mutt_format_s(tmp, sizeof(tmp), prec, mutt_get_name(to));
1125  else if (cc)
1126  mutt_format_s(tmp, sizeof(tmp), prec, mutt_get_name(cc));
1127  else
1128  *tmp = '\0';
1129  }
1130  else
1131  mutt_format_s(tmp, sizeof(tmp), prec, mutt_get_name(from));
1132  p = strpbrk(tmp, " %@");
1133  if (p)
1134  *p = '\0';
1135  mutt_format_s(buf, buflen, prec, tmp);
1136  break;
1137 
1138  case 'W':
1139  if (!optional)
1140  {
1141  mutt_format_s(buf, buflen, prec, e->env->organization ? e->env->organization : "");
1142  }
1143  else if (!e->env->organization)
1144  optional = false;
1145  break;
1146 
1147 #ifdef USE_NNTP
1148  case 'x':
1149  if (!optional)
1150  {
1151  mutt_format_s(buf, buflen, prec, e->env->x_comment_to ? e->env->x_comment_to : "");
1152  }
1153  else if (!e->env->x_comment_to)
1154  optional = false;
1155  break;
1156 #endif
1157 
1158  case 'X':
1159  {
1160  struct Message *msg = mx_msg_open(m, e->msgno);
1161  if (msg)
1162  {
1163  int count = mutt_count_body_parts(m, e, msg->fp);
1164  mx_msg_close(m, &msg);
1165 
1166  /* The recursion allows messages without depth to return 0. */
1167  if (optional)
1168  optional = (count != 0);
1169 
1170  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
1171  snprintf(buf, buflen, fmt, count);
1172  }
1173  break;
1174  }
1175 
1176  case 'y':
1177  if (optional)
1178  optional = (e->env->x_label != NULL);
1179 
1180  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_LABEL);
1181  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(e->env->x_label));
1182  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1183  break;
1184 
1185  case 'Y':
1186  {
1187  bool label = true;
1188  if (e->env->x_label)
1189  {
1190  struct Email *e_tmp = NULL;
1191  if (flags & MUTT_FORMAT_TREE && (e->thread->prev && e->thread->prev->message &&
1192  e->thread->prev->message->env->x_label))
1193  {
1194  e_tmp = e->thread->prev->message;
1195  }
1196  else if (flags & MUTT_FORMAT_TREE &&
1197  (e->thread->parent && e->thread->parent->message &&
1198  e->thread->parent->message->env->x_label))
1199  {
1200  e_tmp = e->thread->parent->message;
1201  }
1202  if (e_tmp && mutt_istr_equal(e->env->x_label, e_tmp->env->x_label))
1203  label = false;
1204  }
1205  else
1206  label = false;
1207 
1208  if (optional)
1209  optional = label;
1210 
1211  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_LABEL);
1212  if (label)
1213  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(e->env->x_label));
1214  else
1215  mutt_format_s(buf + colorlen, buflen - colorlen, prec, "");
1216  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1217  break;
1218  }
1219 
1220  case 'z':
1221  if (src[0] == 's') /* status: deleted/new/old/replied */
1222  {
1223  const char *ch = NULL;
1224  if (e->deleted)
1225  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_DELETED);
1226  else if (e->attach_del)
1227  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_DELETED_ATTACH);
1228  else if (threads && thread_is_new(e))
1229  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_NEW_THREAD);
1230  else if (threads && thread_is_old(e))
1231  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_OLD_THREAD);
1232  else if (e->read && (msg_in_pager != e->msgno))
1233  {
1234  if (e->replied)
1235  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_REPLIED);
1236  else
1237  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_ZEMPTY);
1238  }
1239  else
1240  {
1241  if (e->old)
1242  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_OLD);
1243  else
1244  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_NEW);
1245  }
1246 
1247  snprintf(tmp, sizeof(tmp), "%s", ch);
1248  src++;
1249  }
1250  else if (src[0] == 'c') /* crypto */
1251  {
1252  const char *ch = "";
1253  if ((WithCrypto != 0) && (e->security & SEC_GOODSIGN))
1254  ch = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_GOOD_SIGN);
1255  else if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1256  ch = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_ENCRYPTED);
1257  else if ((WithCrypto != 0) && (e->security & SEC_SIGN))
1258  ch = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_SIGNED);
1259  else if (((WithCrypto & APPLICATION_PGP) != 0) && ((e->security & PGP_KEY) == PGP_KEY))
1260  {
1261  ch = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_CONTAINS_KEY);
1262  }
1263  else
1264  ch = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_NO_CRYPTO);
1265 
1266  snprintf(tmp, sizeof(tmp), "%s", ch);
1267  src++;
1268  }
1269  else if (src[0] == 't') /* tagged, flagged, recipient */
1270  {
1271  const char *ch = "";
1272  if (e->tagged)
1273  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_TAGGED);
1274  else if (e->flagged)
1275  ch = get_nth_wchar(c_flag_chars, FLAG_CHAR_IMPORTANT);
1276  else
1277  ch = get_nth_wchar(c_to_chars, user_is_recipient(e));
1278 
1279  snprintf(tmp, sizeof(tmp), "%s", ch);
1280  src++;
1281  }
1282  else /* fallthrough */
1283  break;
1284 
1285  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_FLAGS);
1286  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
1287  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1288  break;
1289 
1290  case 'Z':
1291  {
1292  /* New/Old for threads; replied; New/Old for messages */
1293  const char *first = NULL;
1294  if (threads && thread_is_new(e))
1295  first = get_nth_wchar(c_flag_chars, FLAG_CHAR_NEW_THREAD);
1296  else if (threads && thread_is_old(e))
1297  first = get_nth_wchar(c_flag_chars, FLAG_CHAR_OLD_THREAD);
1298  else if (e->read && (msg_in_pager != e->msgno))
1299  {
1300  if (e->replied)
1301  first = get_nth_wchar(c_flag_chars, FLAG_CHAR_REPLIED);
1302  else
1303  first = get_nth_wchar(c_flag_chars, FLAG_CHAR_ZEMPTY);
1304  }
1305  else
1306  {
1307  if (e->old)
1308  first = get_nth_wchar(c_flag_chars, FLAG_CHAR_OLD);
1309  else
1310  first = get_nth_wchar(c_flag_chars, FLAG_CHAR_NEW);
1311  }
1312 
1313  /* Marked for deletion; deleted attachments; crypto */
1314  const char *second = "";
1315  if (e->deleted)
1316  second = get_nth_wchar(c_flag_chars, FLAG_CHAR_DELETED);
1317  else if (e->attach_del)
1318  second = get_nth_wchar(c_flag_chars, FLAG_CHAR_DELETED_ATTACH);
1319  else if ((WithCrypto != 0) && (e->security & SEC_GOODSIGN))
1320  second = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_GOOD_SIGN);
1321  else if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1322  second = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_ENCRYPTED);
1323  else if ((WithCrypto != 0) && (e->security & SEC_SIGN))
1324  second = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_SIGNED);
1325  else if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & PGP_KEY))
1326  second = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_CONTAINS_KEY);
1327  else
1328  second = get_nth_wchar(c_crypt_chars, FLAG_CHAR_CRYPT_NO_CRYPTO);
1329 
1330  /* Tagged, flagged and recipient flag */
1331  const char *third = "";
1332  if (e->tagged)
1333  third = get_nth_wchar(c_flag_chars, FLAG_CHAR_TAGGED);
1334  else if (e->flagged)
1335  third = get_nth_wchar(c_flag_chars, FLAG_CHAR_IMPORTANT);
1336  else
1337  third = get_nth_wchar(c_to_chars, user_is_recipient(e));
1338 
1339  snprintf(tmp, sizeof(tmp), "%s%s%s", first, second, third);
1340  }
1341 
1342  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_FLAGS);
1343  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
1344  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1345  break;
1346 
1347  case '@':
1348  {
1349  if (!m)
1350  break;
1351 
1352  const char *end = src;
1353  static unsigned char recurse = 0;
1354 
1355  while ((*end != '\0') && (*end != '@'))
1356  end++;
1357  if ((*end == '@') && (recurse < 20))
1358  {
1359  recurse++;
1360  mutt_strn_copy(tmp, src, end - src, sizeof(tmp));
1361  mutt_expando_format(tmp, sizeof(tmp), col, cols,
1362  NONULL(mutt_idxfmt_hook(tmp, m, e)),
1363  index_format_str, data, flags);
1364  mutt_format_s_x(buf, buflen, prec, tmp, true);
1365  recurse--;
1366 
1367  src = end + 1;
1368  break;
1369  }
1370  }
1371  /* fallthrough */
1372 
1373  default:
1374  snprintf(buf, buflen, "%%%s%c", prec, op);
1375  break;
1376  }
1377 
1378  if (optional)
1379  {
1380  mutt_expando_format(buf, buflen, col, cols, if_str, index_format_str, data, flags);
1381  }
1382  else if (flags & MUTT_FORMAT_OPTIONAL)
1383  {
1384  mutt_expando_format(buf, buflen, col, cols, else_str, index_format_str, data, flags);
1385  }
1386 
1387  /* We return the format string, unchanged */
1388  return src;
1389 }
const char * mutt_addr_for_display(const struct Address *a)
Convert an Address for display purposes.
Definition: address.c:986
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:574
int mutt_count_body_parts(struct Mailbox *m, struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition: attachments.c:252
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:250
@ MT_COLOR_INDEX_AUTHOR
Index: author field (takes a pattern)
Definition: color.h:77
@ MT_COLOR_INDEX_SIZE
Index: size field.
Definition: color.h:86
@ MT_COLOR_INDEX_TAGS
Index: tags field (g, J)
Definition: color.h:87
@ MT_COLOR_INDEX_SUBJECT
Index: subject field (takes a pattern)
Definition: color.h:79
@ MT_COLOR_INDEX_DATE
Index: date field.
Definition: color.h:83
@ MT_COLOR_INDEX_TAG
Index: tag field (g, takes a pattern)
Definition: color.h:80
@ MT_COLOR_INDEX_LABEL
Index: label field.
Definition: color.h:84
@ MT_COLOR_INDEX
Index: default colour (takes a pattern)
Definition: color.h:76
@ MT_COLOR_INDEX_NUMBER
Index: index number.
Definition: color.h:85
@ MT_COLOR_INDEX_FLAGS
Index: flags field (takes a pattern)
Definition: color.h:78
@ MT_COLOR_INDEX_COLLAPSED
Index: number of messages in collapsed thread.
Definition: color.h:82
struct MbTable * cs_subset_mbtable(const struct ConfigSubset *sub, const char *name)
Get a Multibyte table config item by name.
Definition: helpers.c:145
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_format_s_x(char *buf, size_t buflen, const char *prec, const char *s, bool arboreal)
Format a string like snprintf()
Definition: curs_lib.c:753
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:654
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone.
Definition: date.c:672
#define MUTT_DATE_NOW
Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime()
Definition: date.h:39
size_t email_size(const struct Email *e)
Compute the size of an email.
Definition: email.c:125
#define MUTT_FORMAT_INDEX
This is a main index entry.
Definition: format_flags.h:36
#define MUTT_FORMAT_TREE
Draw the thread tree.
Definition: format_flags.h:32
#define MUTT_FORMAT_PLAIN
Do not prepend DISP_TO, DISP_CC ...
Definition: format_flags.h:38
static const char * index_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the index list - Implements format_t -.
Definition: hdrline.c:439
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
@ FLAG_CHAR_CRYPT_CONTAINS_KEY
Character denoting a message contains a PGP key.
Definition: hdrline.c:100
@ FLAG_CHAR_CRYPT_SIGNED
Character denoting a message is signed.
Definition: hdrline.c:99
@ FLAG_CHAR_CRYPT_NO_CRYPTO
Character denoting a message has no cryptography information.
Definition: hdrline.c:101
@ FLAG_CHAR_CRYPT_GOOD_SIGN
Character denoting a message signed with a verified key.
Definition: hdrline.c:97
@ FLAG_CHAR_CRYPT_ENCRYPTED
Character denoting a message is PGP-encrypted.
Definition: hdrline.c:98
static void make_from_addr(struct Envelope *env, char *buf, size_t buflen, bool do_lists)
Create a 'from' address for a reply email.
Definition: hdrline.c:277
static const char * get_nth_wchar(const struct MbTable *table, int index)
Extract one char from a multi-byte table.
Definition: hdrline.c:166
static bool thread_is_old(struct Email *e)
Does the email thread contain any unread emails?
Definition: hdrline.c:377
static int user_is_recipient(struct Email *e)
Is the user a recipient of the message.
Definition: hdrline.c:327
static size_t add_index_color(char *buf, size_t buflen, MuttFormatFlags flags, enum ColorId color)
Insert a color marker into a string.
Definition: hdrline.c:129
static void make_from(struct Envelope *env, char *buf, size_t buflen, bool do_lists, MuttFormatFlags flags)
Generate a From: field (with optional prefix)
Definition: hdrline.c:221
static bool thread_is_new(struct Email *e)
Does the email thread contain any new emails?
Definition: hdrline.c:367
@ FLAG_CHAR_OLD
Character denoting an email that has been read.
Definition: hdrline.c:84
@ FLAG_CHAR_REPLIED
Character denoting an email that has been replied to.
Definition: hdrline.c:83
@ FLAG_CHAR_OLD_THREAD
Character denoting a thread of emails that has been read.
Definition: hdrline.c:86
@ FLAG_CHAR_ZEMPTY
Character denoting a read email, $index_format Z expando.
Definition: hdrline.c:89
@ FLAG_CHAR_TAGGED
Character denoting a tagged email.
Definition: hdrline.c:79
@ FLAG_CHAR_NEW
Character denoting an unread email.
Definition: hdrline.c:85
@ FLAG_CHAR_DELETED
Character denoting a deleted email.
Definition: hdrline.c:81
@ FLAG_CHAR_NEW_THREAD
Character denoting a thread containing at least one new email.
Definition: hdrline.c:87
@ FLAG_CHAR_DELETED_ATTACH
Character denoting a deleted attachment.
Definition: hdrline.c:82
@ FLAG_CHAR_SEMPTY
Character denoting a read email, $index_format S expando.
Definition: hdrline.c:88
@ FLAG_CHAR_IMPORTANT
Character denoting a important (flagged) email.
Definition: hdrline.c:80
const char * mutt_idxfmt_hook(const char *name, struct Mailbox *m, struct Email *e)
Get index-format-hook format string.
Definition: hook.c:948
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
bool check_for_mailing_list(struct AddressList *al, const char *pfx, char *buf, int buflen)
Search list of addresses for a mailing list.
Definition: maillist.c:78
bool check_for_mailing_list_addr(struct AddressList *al, char *buf, int buflen)
Check an address list for a mailing list.
Definition: maillist.c:102
bool first_mailing_list(char *buf, size_t buflen, struct AddressList *al)
Get the first mailing list in the list of addresses.
Definition: maillist.c:124
bool mutt_mb_get_initials(const char *name, char *buf, size_t buflen)
Turn a name into initials.
Definition: mbyte.c:82
#define FREE(x)
Definition: memory.h:43
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:796
char * mutt_strn_copy(char *dest, const char *src, size_t len, size_t dsize)
Copy a sub-string into a buffer.
Definition: string.c:408
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:629
int mutt_messages_in_thread(struct Mailbox *m, struct Email *e, enum MessageInThread mit)
Count the messages in a thread.
Definition: mutt_thread.c:1608
#define mutt_using_threads()
Definition: mutt_thread.h:100
@ MIT_NUM_MESSAGES
How many messages are in the thread.
Definition: mutt_thread.h:75
@ MIT_POSITION
Our position in the thread.
Definition: mutt_thread.h:76
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1193
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1147
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:80
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define PGP_KEY
Definition: lib.h:99
#define WithCrypto
Definition: lib.h:116
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
char * nm_email_get_folder_rel_db(struct Mailbox *m, struct Email *e)
Get the folder for a Email from the same level as the notmuch database.
Definition: notmuch.c:1468
#define TAILQ_FIRST(head)
Definition: queue.h:723
const char * mutt_get_name(const struct Address *a)
Pick the best name to display from an address.
Definition: sort.c:136
An email address.
Definition: address.h:36
The envelope/body of an email.
Definition: email.h:37
bool read
Email is read.
Definition: email.h:48
unsigned int zminutes
Minutes away from UTC.
Definition: email.h:55
struct Envelope * env
Envelope information.
Definition: email.h:66
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:120
int lines
How many lines in the body of this message?
Definition: email.h:60
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
struct Body * body
List of MIME parts.
Definition: email.h:67
char * tree
Character string to print thread tree.
Definition: email.h:124
bool old
Email is seen, but unread.
Definition: email.h:47
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:122
bool zoccident
True, if west of UTC, False if east.
Definition: email.h:56
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:99
bool flagged
Marked important?
Definition: email.h:45
unsigned int zhours
Hours away from UTC.
Definition: email.h:54
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:58
bool replied
Email has been replied to.
Definition: email.h:49
struct TagList tags
For drivers that support server tagging.
Definition: email.h:70
int score
Message score.
Definition: email.h:113
int msgno
Number displayed to the user.
Definition: email.h:111
bool deleted
Email is deleted.
Definition: email.h:76
bool tagged
Email is tagged.
Definition: email.h:107
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:59
struct MuttThread * thread
Thread of Emails.
Definition: email.h:119
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:64
char * message_id
Message ID.
Definition: envelope.h:73
char * x_comment_to
List of 'X-comment-to' fields.
Definition: envelope.h:82
char * newsgroups
List of newsgroups.
Definition: envelope.h:79
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct Buffer spam
Spam header.
Definition: envelope.h:84
char * subject
Email's subject.
Definition: envelope.h:70
char * organization
Organisation header.
Definition: envelope.h:77
char * x_label
X-Label.
Definition: envelope.h:76
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:72
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
Data passed to index_format_str()
Definition: hdrline.c:67
struct Email * email
Current Email.
Definition: hdrline.c:70
int msg_in_pager
Index of Email displayed in the Pager.
Definition: hdrline.c:69
struct Mailbox * mailbox
Current Mailbox.
Definition: hdrline.c:68
const char * pager_progress
String representing Pager position through Email.
Definition: hdrline.c:71
int msg_count
Total number of messages.
Definition: mailbox.h:88
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
Multibyte character table.
Definition: mbtable.h:34
int len
Number of characters.
Definition: mbtable.h:36
char ** chars
The array of multibyte character strings.
Definition: mbtable.h:37
A local copy of an email.
Definition: mxapi.h:43
FILE * fp
pointer to the message data
Definition: mxapi.h:44
struct Message::@0 flags
Flags for the Message.
struct MuttThread * parent
Parent of this Thread.
Definition: thread.h:45
struct MuttThread * prev
Previous sibling Thread.
Definition: thread.h:48
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
bool subjrx_apply_mods(struct Envelope *env)
Apply regex modifications to the subject.
Definition: subjectrx.c:128
char * driver_tags_get_transformed_for(struct TagList *head, const char *name)
Get transformed tag for a tag name from a header.
Definition: tags.c:172
struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: tags.c:39
char * driver_tags_get_transformed(struct TagList *list)
Get transformed tags.
Definition: tags.c:133
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ history_format_str()

static const char* history_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the history list - Implements format_t -.

Expando Description
%s History match

Definition at line 92 of file dlg_history.c.

96 {
97  char *match = (char *) data;
98 
99  switch (op)
100  {
101  case 's':
102  mutt_format_s(buf, buflen, prec, match);
103  break;
104  }
105 
106  return src;
107 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_format_str()

static const char* mix_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the remailer menu - Implements format_t -.

Expando Description
%a The remailer's e-mail address
%c Remailer capabilities
%n The running number on the menu
%s The remailer's short name

Definition at line 119 of file win_hosts.c.

123 {
124  char fmt[128];
125  struct Remailer *remailer = (struct Remailer *) data;
126  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
127 
128  switch (op)
129  {
130  case 'a':
131  if (!optional)
132  {
133  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
134  snprintf(buf, buflen, fmt, NONULL(remailer->addr));
135  }
136  else if (!remailer->addr)
137  optional = false;
138  break;
139 
140  case 'c':
141  if (optional)
142  break;
143 
144  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
145  snprintf(buf, buflen, fmt, mix_format_caps(remailer));
146  break;
147 
148  case 'n':
149  if (optional)
150  break;
151 
152  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
153  snprintf(buf, buflen, fmt, remailer->num);
154  break;
155 
156  case 's':
157  if (!optional)
158  {
159  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
160  snprintf(buf, buflen, fmt, NONULL(remailer->shortname));
161  }
162  else if (!remailer->shortname)
163  optional = false;
164  break;
165 
166  default:
167  *buf = '\0';
168  }
169 
170  if (optional)
171  {
172  mutt_expando_format(buf, buflen, col, cols, if_str, mix_format_str, data,
174  }
175  else if (flags & MUTT_FORMAT_OPTIONAL)
176  {
177  mutt_expando_format(buf, buflen, col, cols, else_str, mix_format_str, data,
179  }
180 
181  /* We return the format string, unchanged */
182  return src;
183 }
static const char * mix_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the remailer menu - Implements format_t -.
Definition: win_hosts.c:119
A Mixmaster remailer.
Definition: remailer.h:40
int num
Index number.
Definition: remailer.h:41
char * addr
Address of host.
Definition: remailer.h:43
char * shortname
Short name of remailer host.
Definition: remailer.h:42
static const char * mix_format_caps(struct Remailer *r)
Turn flags into a MixMaster capability string.
Definition: win_hosts.c:67
+ 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 777 of file muttlib.c.

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

◆ crypt_format_str()

static const char* crypt_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the key selection menu - Implements format_t -.

Expando Description
%n Number
%p Protocol
%t Trust/validity of the key-uid association
%u User id
%[fmt] Date of key using strftime(3)

| | | %a | Algorithm | %c | Capabilities | %f | Flags | %k | Key id | %l | Length | | | %A | Algorithm of the principal key | %C | Capabilities of the principal key | %F | Flags of the principal key | %K | Key id of the principal key | %L | Length of the principal key

Definition at line 364 of file dlg_gpgme.c.

368 {
369  char fmt[128];
370  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
371 
372  struct CryptEntry *entry = (struct CryptEntry *) data;
373  struct CryptKeyInfo *key = entry->key;
374 
375  /* if (isupper ((unsigned char) op)) */
376  /* key = pkey; */
377 
378  KeyFlags kflags = (key->flags /* | (pkey->flags & KEYFLAG_RESTRICTIONS)
379  | uid->flags */);
380 
381  switch (tolower(op))
382  {
383  case 'a':
384  if (!optional)
385  {
386  const char *s = NULL;
387  snprintf(fmt, sizeof(fmt), "%%%s.3s", prec);
388  if (key->kobj->subkeys)
389  s = gpgme_pubkey_algo_name(key->kobj->subkeys->pubkey_algo);
390  else
391  s = "?";
392  snprintf(buf, buflen, fmt, s);
393  }
394  break;
395 
396  case 'c':
397  if (!optional)
398  {
399  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
400  snprintf(buf, buflen, fmt, crypt_key_abilities(kflags));
401  }
402  else if (!(kflags & KEYFLAG_ABILITIES))
403  optional = false;
404  break;
405 
406  case 'f':
407  if (!optional)
408  {
409  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
410  snprintf(buf, buflen, fmt, crypt_flags(kflags));
411  }
412  else if (!(kflags & KEYFLAG_RESTRICTIONS))
413  optional = false;
414  break;
415 
416  case 'k':
417  if (!optional)
418  {
419  /* fixme: we need a way to distinguish between main and subkeys.
420  * Store the idx in entry? */
421  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
422  snprintf(buf, buflen, fmt, crypt_keyid(key));
423  }
424  break;
425 
426  case 'l':
427  if (!optional)
428  {
429  snprintf(fmt, sizeof(fmt), "%%%slu", prec);
430  unsigned long val;
431  if (key->kobj->subkeys)
432  val = key->kobj->subkeys->length;
433  else
434  val = 0;
435  snprintf(buf, buflen, fmt, val);
436  }
437  break;
438 
439  case 'n':
440  if (!optional)
441  {
442  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
443  snprintf(buf, buflen, fmt, entry->num);
444  }
445  break;
446 
447  case 'p':
448  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
449  snprintf(buf, buflen, fmt, gpgme_get_protocol_name(key->kobj->protocol));
450  break;
451 
452  case 't':
453  {
454  char *s = NULL;
455  if ((kflags & KEYFLAG_ISX509))
456  s = "x";
457  else
458  {
459  switch (key->validity)
460  {
461  case GPGME_VALIDITY_FULL:
462  s = "f";
463  break;
464  case GPGME_VALIDITY_MARGINAL:
465  s = "m";
466  break;
467  case GPGME_VALIDITY_NEVER:
468  s = "n";
469  break;
470  case GPGME_VALIDITY_ULTIMATE:
471  s = "u";
472  break;
473  case GPGME_VALIDITY_UNDEFINED:
474  s = "q";
475  break;
476  case GPGME_VALIDITY_UNKNOWN:
477  default:
478  s = "?";
479  break;
480  }
481  }
482  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
483  snprintf(buf, buflen, fmt, *s);
484  break;
485  }
486 
487  case 'u':
488  if (!optional)
489  {
490  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
491  snprintf(buf, buflen, fmt, key->uid);
492  }
493  break;
494 
495  case '[':
496  {
497  char buf2[128];
498  bool do_locales = true;
499  struct tm tm = { 0 };
500 
501  char *p = buf;
502 
503  const char *cp = src;
504  if (*cp == '!')
505  {
506  do_locales = false;
507  cp++;
508  }
509 
510  size_t len = buflen - 1;
511  while ((len > 0) && (*cp != ']'))
512  {
513  if (*cp == '%')
514  {
515  cp++;
516  if (len >= 2)
517  {
518  *p++ = '%';
519  *p++ = *cp;
520  len -= 2;
521  }
522  else
523  break; /* not enough space */
524  cp++;
525  }
526  else
527  {
528  *p++ = *cp++;
529  len--;
530  }
531  }
532  *p = '\0';
533 
534  if (key->kobj->subkeys && (key->kobj->subkeys->timestamp > 0))
535  tm = mutt_date_localtime(key->kobj->subkeys->timestamp);
536  else
537  tm = mutt_date_localtime(0); // Default to 1970-01-01
538 
539  if (!do_locales)
540  setlocale(LC_TIME, "C");
541  strftime(buf2, sizeof(buf2), buf, &tm);
542  if (!do_locales)
543  setlocale(LC_TIME, "");
544 
545  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
546  snprintf(buf, buflen, fmt, buf2);
547  if (len > 0)
548  src = cp + 1;
549  break;
550  }
551 
552  default:
553  *buf = '\0';
554  }
555 
556  if (optional)
557  {
558  mutt_expando_format(buf, buflen, col, cols, if_str, crypt_format_str, data,
560  }
561  else if (flags & MUTT_FORMAT_OPTIONAL)
562  {
563  mutt_expando_format(buf, buflen, col, cols, else_str, crypt_format_str,
564  data, MUTT_FORMAT_NO_FLAGS);
565  }
566 
567  /* We return the format string, unchanged */
568  return src;
569 }
const char * crypt_keyid(struct CryptKeyInfo *k)
Find the ID for the key.
Definition: crypt_gpgme.c:358
static char crypt_flags(KeyFlags flags)
Parse the key flags into a single character.
Definition: dlg_gpgme.c:327
static char * crypt_key_abilities(KeyFlags flags)
Parse key flags into a string.
Definition: dlg_gpgme.c:297
static const char * crypt_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the key selection menu - Implements format_t -.
Definition: dlg_gpgme.c:364
#define KEYFLAG_ISX509
Key is an X.509 key.
Definition: lib.h:129
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
Definition: lib.h:125
#define KEYFLAG_RESTRICTIONS
Definition: lib.h:140
#define KEYFLAG_ABILITIES
Definition: lib.h:142
An entry in the Select-Key menu.
Definition: dlg_gpgme.c:111
struct CryptKeyInfo * key
Key.
Definition: dlg_gpgme.c:113
size_t num
Index number.
Definition: dlg_gpgme.c:112
A stored PGP key.
Definition: crypt_gpgme.h:44
gpgme_validity_t validity
uid validity (cached for convenience)
Definition: crypt_gpgme.h:50
KeyFlags flags
global and per uid flags (for convenience)
Definition: crypt_gpgme.h:49
const char * uid
and for convenience point to this user ID
Definition: crypt_gpgme.h:48
gpgme_key_t kobj
Definition: crypt_gpgme.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_entry_format_str()

static const char* pgp_entry_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format an entry on the PGP key selection menu - Implements format_t -.

Expando Description
%n Number
%t Trust/validity of the key-uid association
%u User id
%[fmt] Date of key using strftime(3)

| | | %a | Algorithm | %c | Capabilities | %f | Flags | %k | Key id | %l | Length | | | %A | Algorithm of the principal key | %C | Capabilities of the principal key | %F | Flags of the principal key | %K | Key id of the principal key | %L | Length of the principal key

Definition at line 339 of file dlg_pgp.c.

343 {
344  char fmt[128];
345  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
346 
347  struct PgpEntry *entry = (struct PgpEntry *) data;
348  struct PgpUid *uid = entry->uid;
349  struct PgpKeyInfo *key = uid->parent;
350  struct PgpKeyInfo *pkey = pgp_principal_key(key);
351 
352  if (isupper((unsigned char) op))
353  key = pkey;
354 
355  KeyFlags kflags = key->flags | (pkey->flags & KEYFLAG_RESTRICTIONS) | uid->flags;
356 
357  switch (tolower(op))
358  {
359  case 'a':
360  if (!optional)
361  {
362  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
363  snprintf(buf, buflen, fmt, key->algorithm);
364  }
365  break;
366  case 'c':
367  if (!optional)
368  {
369  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
370  snprintf(buf, buflen, fmt, pgp_key_abilities(kflags));
371  }
372  else if (!(kflags & KEYFLAG_ABILITIES))
373  optional = false;
374  break;
375  case 'f':
376  if (!optional)
377  {
378  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
379  snprintf(buf, buflen, fmt, pgp_flags(kflags));
380  }
381  else if (!(kflags & KEYFLAG_RESTRICTIONS))
382  optional = false;
383  break;
384  case 'k':
385  if (!optional)
386  {
387  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
388  snprintf(buf, buflen, fmt, pgp_this_keyid(key));
389  }
390  break;
391  case 'l':
392  if (!optional)
393  {
394  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
395  snprintf(buf, buflen, fmt, key->keylen);
396  }
397  break;
398  case 'n':
399  if (!optional)
400  {
401  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
402  snprintf(buf, buflen, fmt, entry->num);
403  }
404  break;
405  case 't':
406  if (!optional)
407  {
408  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
409  snprintf(buf, buflen, fmt, trust_flags[uid->trust & 0x03]);
410  }
411  else if (!(uid->trust & 0x03))
412  {
413  /* undefined trust */
414  optional = false;
415  }
416  break;
417  case 'u':
418  if (!optional)
419  {
420  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
421  snprintf(buf, buflen, fmt, NONULL(uid->addr));
422  }
423  break;
424  case '[':
425 
426  {
427  char buf2[128];
428  bool do_locales = true;
429  size_t len;
430 
431  char *p = buf;
432 
433  const char *cp = src;
434  if (*cp == '!')
435  {
436  do_locales = false;
437  cp++;
438  }
439 
440  len = buflen - 1;
441  while ((len > 0) && (*cp != ']'))
442  {
443  if (*cp == '%')
444  {
445  cp++;
446  if (len >= 2)
447  {
448  *p++ = '%';
449  *p++ = *cp;
450  len -= 2;
451  }
452  else
453  break; /* not enough space */
454  cp++;
455  }
456  else
457  {
458  *p++ = *cp++;
459  len--;
460  }
461  }
462  *p = '\0';
463 
464  if (!do_locales)
465  setlocale(LC_TIME, "C");
466  mutt_date_localtime_format(buf2, sizeof(buf2), buf, key->gen_time);
467  if (!do_locales)
468  setlocale(LC_TIME, "");
469 
470  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
471  snprintf(buf, buflen, fmt, buf2);
472  if (len > 0)
473  src = cp + 1;
474  break;
475  }
476  default:
477  *buf = '\0';
478  }
479 
480  if (optional)
481  {
482  mutt_expando_format(buf, buflen, col, cols, if_str, pgp_entry_format_str,
483  data, MUTT_FORMAT_NO_FLAGS);
484  }
485  else if (flags & MUTT_FORMAT_OPTIONAL)
486  {
487  mutt_expando_format(buf, buflen, col, cols, else_str, pgp_entry_format_str,
488  data, MUTT_FORMAT_NO_FLAGS);
489  }
490 
491  /* We return the format string, unchanged */
492  return src;
493 }
static const char trust_flags[]
Definition: dlg_pgp.c:113
static char pgp_flags(KeyFlags flags)
Turn PGP key flags into a string.
Definition: dlg_pgp.c:303
static char * pgp_key_abilities(KeyFlags flags)
Turn PGP key abilities into a string.
Definition: dlg_pgp.c:275
static const char * pgp_entry_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format an entry on the PGP key selection menu - Implements format_t -.
Definition: dlg_pgp.c:339
char * pgp_this_keyid(struct PgpKeyInfo *k)
Get the ID of this key.
Definition: pgp.c:191
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition: pgpkey.c:89
An entry in a PGP key menu.
Definition: dlg_pgp.c:108
struct PgpUid * uid
Definition: dlg_pgp.c:110
size_t num
Index number.
Definition: dlg_pgp.c:109
Information about a PGP key.
Definition: pgplib.h:47
KeyFlags flags
Definition: pgplib.h:51
short keylen
Definition: pgplib.h:52
time_t gen_time
Definition: pgplib.h:53
const char * algorithm
Definition: pgplib.h:55
PGP User ID.
Definition: pgplib.h:35
short trust
Definition: pgplib.h:37
struct PgpKeyInfo * parent
Parent key.
Definition: pgplib.h:39
int flags
Definition: pgplib.h:38
char * addr
Definition: pgplib.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_command_format_str()

static const char* pgp_command_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a PGP command string - Implements format_t -.

Expando Description
%a Value of $pgp_sign_as if set, otherwise $pgp_default_key
%f File containing a message
%p Expands to PGPPASSFD=0 when a pass phrase is needed, to an empty string otherwise
%r One or more key IDs (or fingerprints if available)
%s File containing the signature part of a multipart/signed attachment when verifying it

Definition at line 79 of file pgpinvoke.c.

83 {
84  char fmt[128];
85  struct PgpCommandContext *cctx = (struct PgpCommandContext *) data;
86  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
87 
88  switch (op)
89  {
90  case 'a':
91  {
92  if (!optional)
93  {
94  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
95  snprintf(buf, buflen, fmt, NONULL(cctx->signas));
96  }
97  else if (!cctx->signas)
98  optional = false;
99  break;
100  }
101  case 'f':
102  {
103  if (!optional)
104  {
105  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
106  snprintf(buf, buflen, fmt, NONULL(cctx->fname));
107  }
108  else if (!cctx->fname)
109  optional = false;
110  break;
111  }
112  case 'p':
113  {
114  if (!optional)
115  {
116  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
117  snprintf(buf, buflen, fmt, cctx->need_passphrase ? "PGPPASSFD=0" : "");
118  }
119  else if (!cctx->need_passphrase || pgp_use_gpg_agent())
120  optional = false;
121  break;
122  }
123  case 'r':
124  {
125  if (!optional)
126  {
127  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
128  snprintf(buf, buflen, fmt, NONULL(cctx->ids));
129  }
130  else if (!cctx->ids)
131  optional = false;
132  break;
133  }
134  case 's':
135  {
136  if (!optional)
137  {
138  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
139  snprintf(buf, buflen, fmt, NONULL(cctx->sig_fname));
140  }
141  else if (!cctx->sig_fname)
142  optional = false;
143  break;
144  }
145  default:
146  {
147  *buf = '\0';
148  break;
149  }
150  }
151 
152  if (optional)
153  {
154  mutt_expando_format(buf, buflen, col, cols, if_str, pgp_command_format_str,
155  data, MUTT_FORMAT_NO_FLAGS);
156  }
157  else if (flags & MUTT_FORMAT_OPTIONAL)
158  {
159  mutt_expando_format(buf, buflen, col, cols, else_str,
161  }
162 
163  /* We return the format string, unchanged */
164  return src;
165 }
static const char * pgp_command_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a PGP command string - Implements format_t -.
Definition: pgpinvoke.c:79
bool pgp_use_gpg_agent(void)
Does the user want to use the gpg agent?
Definition: pgp.c:127
Data for a PGP command.
Definition: pgpinvoke.c:60
bool need_passphrase
p
Definition: pgpinvoke.c:61
const char * signas
a
Definition: pgpinvoke.c:64
const char * fname
f
Definition: pgpinvoke.c:62
const char * ids
r
Definition: pgpinvoke.c:65
const char * sig_fname
s
Definition: pgpinvoke.c:63
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ smime_command_format_str()

static const char* smime_command_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format an SMIME command - Implements format_t -.

Expando Description
%a Algorithm used for encryption
%C CA location: Depending on whether $smime_ca_location points to a directory or file
%c One or more certificate IDs
%d Message digest algorithm specified with $smime_sign_digest_alg
%f File containing a message
%i Intermediate certificates
%k The key-pair specified with $smime_default_key
%s File containing the signature part of a multipart/signed attachment when verifying it

Definition at line 218 of file smime.c.

223 {
224  char fmt[128];
225  struct SmimeCommandContext *cctx = (struct SmimeCommandContext *) data;
226  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
227 
228  switch (op)
229  {
230  case 'C':
231  {
232  const char *const c_smime_ca_location = cs_subset_path(NeoMutt->sub, "smime_ca_location");
233  if (!optional)
234  {
235  struct Buffer *path = mutt_buffer_pool_get();
236  struct Buffer *buf1 = mutt_buffer_pool_get();
237  struct Buffer *buf2 = mutt_buffer_pool_get();
238  struct stat st = { 0 };
239 
240  mutt_buffer_strcpy(path, c_smime_ca_location);
243 
244  if ((stat(mutt_buffer_string(path), &st) != 0) || !S_ISDIR(st.st_mode))
245  mutt_buffer_printf(buf2, "-CAfile %s", mutt_buffer_string(buf1));
246  else
247  mutt_buffer_printf(buf2, "-CApath %s", mutt_buffer_string(buf1));
248 
249  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
250  snprintf(buf, buflen, fmt, mutt_buffer_string(buf2));
251 
255  }
256  else if (!c_smime_ca_location)
257  optional = false;
258  break;
259  }
260 
261  case 'c':
262  { /* certificate (list) */
263  if (!optional)
264  {
265  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
266  snprintf(buf, buflen, fmt, NONULL(cctx->certificates));
267  }
268  else if (!cctx->certificates)
269  optional = false;
270  break;
271  }
272 
273  case 'i':
274  { /* intermediate certificates */
275  if (!optional)
276  {
277  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
278  snprintf(buf, buflen, fmt, NONULL(cctx->intermediates));
279  }
280  else if (!cctx->intermediates)
281  optional = false;
282  break;
283  }
284 
285  case 's':
286  { /* detached signature */
287  if (!optional)
288  {
289  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
290  snprintf(buf, buflen, fmt, NONULL(cctx->sig_fname));
291  }
292  else if (!cctx->sig_fname)
293  optional = false;
294  break;
295  }
296 
297  case 'k':
298  { /* private key */
299  if (!optional)
300  {
301  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
302  snprintf(buf, buflen, fmt, NONULL(cctx->key));
303  }
304  else if (!cctx->key)
305  optional = false;
306  break;
307  }
308 
309  case 'a':
310  { /* algorithm for encryption */
311  if (!optional)
312  {
313  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
314  snprintf(buf, buflen, fmt, NONULL(cctx->cryptalg));
315  }
316  else if (!cctx->key)
317  optional = false;
318  break;
319  }
320 
321  case 'f':
322  { /* file to process */
323  if (!optional)
324  {
325  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
326  snprintf(buf, buflen, fmt, NONULL(cctx->fname));
327  }
328  else if (!cctx->fname)
329  optional = false;
330  break;
331  }
332 
333  case 'd':
334  { /* algorithm for the signature message digest */
335  if (!optional)
336  {
337  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
338  snprintf(buf, buflen, fmt, NONULL(cctx->digestalg));
339  }
340  else if (!cctx->key)
341  optional = false;
342  break;
343  }
344 
345  default:
346  *buf = '\0';
347  break;
348  }
349 
350  if (optional)
351  {
352  mutt_expando_format(buf, buflen, col, cols, if_str,
354  }
355  else if (flags & MUTT_FORMAT_OPTIONAL)
356  {
357  mutt_expando_format(buf, buflen, col, cols, else_str,
359  }
360 
361  /* We return the format string, unchanged */
362  return src;
363 }
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:158
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
static const char * smime_command_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format an SMIME command - Implements format_t -.
Definition: smime.c:218
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
Data for a SIME command.
Definition: smime.c:68
const char * sig_fname
s
Definition: smime.c:73
const char * intermediates
i
Definition: smime.c:75
const char * digestalg
d
Definition: smime.c:71
const char * cryptalg
a
Definition: smime.c:70
const char * key
k
Definition: smime.c:69
const char * fname
f
Definition: smime.c:72
const char * certificates
c
Definition: smime.c:74
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_index_format_str()

const char* group_index_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)

Format a string for the newsgroup menu - Implements format_t -.

Expando Description
%C Current newsgroup number
%d Description of newsgroup (becomes from server)
%f Newsgroup name
%M - if newsgroup not allowed for direct post (moderated for example)
%N N if newsgroup is new, u if unsubscribed, blank otherwise
%n Number of new articles in newsgroup
%s Number of unread articles in newsgroup

Definition at line 55 of file browse.c.

59 {
60  char fn[128], fmt[128];
61  struct Folder *folder = (struct Folder *) data;
62 
63  switch (op)
64  {
65  case 'C':
66  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
67  snprintf(buf, buflen, fmt, folder->num + 1);
68  break;
69 
70  case 'd':
71  if (folder->ff->nd->desc)
72  {
73  char *desc = mutt_str_dup(folder->ff->nd->desc);
74  const char *const c_newsgroups_charset = cs_subset_string(NeoMutt->sub, "newsgroups_charset");
75  const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
76  if (c_newsgroups_charset)
77  mutt_ch_convert_string(&desc, c_newsgroups_charset, c_charset, MUTT_ICONV_HOOK_FROM);
79 
80  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
81  snprintf(buf, buflen, fmt, desc);
82  FREE(&desc);
83  }
84  else
85  {
86  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
87  snprintf(buf, buflen, fmt, "");
88  }
89  break;
90 
91  case 'f':
92  mutt_str_copy(fn, folder->ff->name, sizeof(fn));
93  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
94  snprintf(buf, buflen, fmt, fn);
95  break;
96 
97  case 'M':
98  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
99  if (folder->ff->nd->deleted)
100  snprintf(buf, buflen, fmt, 'D');
101  else
102  snprintf(buf, buflen, fmt, folder->ff->nd->allowed ? ' ' : '-');
103  break;
104 
105  case 'N':
106  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
107  if (folder->ff->nd->subscribed)
108  snprintf(buf, buflen, fmt, ' ');
109  else
110  snprintf(buf, buflen, fmt, folder->ff->has_new_mail ? 'N' : 'u');
111  break;
112 
113  case 'n':
114  {
115  const bool c_mark_old = cs_subset_bool(NeoMutt->sub, "mark_old");
116  if (c_mark_old && (folder->ff->nd->last_cached >= folder->ff->nd->first_message) &&
117  (folder->ff->nd->last_cached <= folder->ff->nd->last_message))
118  {
119  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
120  snprintf(buf, buflen, fmt, folder->ff->nd->last_message - folder->ff->nd->last_cached);
121  }
122  else
123  {
124  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
125  snprintf(buf, buflen, fmt, folder->ff->nd->unread);
126  }
127  break;
128  }
129 
130  case 's':
131  if (flags & MUTT_FORMAT_OPTIONAL)
132  {
133  if (folder->ff->nd->unread != 0)
134  {
135  mutt_expando_format(buf, buflen, col, cols, if_str,
136  group_index_format_str, data, flags);
137  }
138  else
139  {
140  mutt_expando_format(buf, buflen, col, cols, else_str,
141  group_index_format_str, data, flags);
142  }
143  }
144  else
145  {
146  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
147  snprintf(buf, buflen, fmt, folder->ff->nd->unread);
148  }
149  break;
150  }
151  return src;
152 }
const char * group_index_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the newsgroup menu - Implements format_t -.
Definition: browse.c:55
int mutt_mb_filter_unprintable(char **s)
Replace unprintable characters.
Definition: mbyte.c:421
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:752
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
Definition: charset.h:72
struct NntpMboxData * nd
Extra NNTP data.
Definition: lib.h:99
anum_t last_cached
Definition: mdata.h:39
bool deleted
Definition: mdata.h:44
bool allowed
Definition: mdata.h:43
anum_t last_message
Definition: mdata.h:37
char * desc
Description of newsgroup.
Definition: mdata.h:35
anum_t unread
Definition: mdata.h:40
anum_t first_message
Definition: mdata.h:36
bool subscribed
Definition: mdata.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_format_str()

const char* nntp_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)

Expand the newsrc filename - Implements format_t -.

Expando Description
%a Account url
%p Port
%P Port if specified
%s News server name
%S Url schema
%u Username

Definition at line 924 of file newsrc.c.

927 {
928  struct NntpAccountData *adata = (struct NntpAccountData *) data;
929  struct ConnAccount *cac = &adata->conn->account;
930  char fn[128], fmt[128];
931 
932  switch (op)
933  {
934  case 'a':
935  {
936  struct Url url = { 0 };
937  mutt_account_tourl(cac, &url);
938  url_tostring(&url, fn, sizeof(fn), U_PATH);
939  char *p = strchr(fn, '/');
940  if (p)
941  *p = '\0';
942  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
943  snprintf(buf, buflen, fmt, fn);
944  break;
945  }
946  case 'p':
947  snprintf(fmt, sizeof(fmt), "%%%su", prec);
948  snprintf(buf, buflen, fmt, cac->port);
949  break;
950  case 'P':
951  *buf = '\0';
952  if (cac->flags & MUTT_ACCT_PORT)
953  {
954  snprintf(fmt, sizeof(fmt), "%%%su", prec);
955  snprintf(buf, buflen, fmt, cac->port);
956  }
957  break;
958  case 's':
959  mutt_str_copy(fn, cac->host, sizeof(fn));
960  mutt_str_lower(fn);
961  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
962  snprintf(buf, buflen, fmt, fn);
963  break;
964  case 'S':
965  {
966  struct Url url = { 0 };
967  mutt_account_tourl(cac, &url);
968  url_tostring(&url, fn, sizeof(fn), U_PATH);
969  char *p = strchr(fn, ':');
970  if (p)
971  *p = '\0';
972  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
973  snprintf(buf, buflen, fmt, fn);
974  break;
975  }
976  case 'u':
977  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
978  snprintf(buf, buflen, fmt, cac->user);
979  break;
980  }
981  return src;
982 }
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:43
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Login details for a remote server.
Definition: connaccount.h:53
char user[128]
Username.
Definition: connaccount.h:56
char host[128]
Server to login to.
Definition: connaccount.h:54
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:60
unsigned short port
Port to connect to.
Definition: connaccount.h:58
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
NNTP-specific Account data -.
Definition: adata.h:37
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:63
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:69
char * src
Raw URL string.
Definition: url.h:77
int url_tostring(struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:418
#define U_PATH
Definition: url.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pattern_format_str()

static const char* pattern_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the pattern completion menu - Implements format_t -.

Expando Description
%d Pattern description
%e Pattern expression
%n Index number

Definition at line 107 of file dlg_pattern.c.

111 {
112  struct PatternEntry *entry = (struct PatternEntry *) data;
113 
114  switch (op)
115  {
116  case 'd':
117  mutt_format_s(buf, buflen, prec, NONULL(entry->desc));
118  break;
119  case 'e':
120  mutt_format_s(buf, buflen, prec, NONULL(entry->expr));
121  break;
122  case 'n':
123  {
124  char tmp[32];
125  snprintf(tmp, sizeof(tmp), "%%%sd", prec);
126  snprintf(buf, buflen, tmp, entry->num);
127  break;
128  }
129  }
130 
131  return src;
132 }
A line in the Pattern Completion menu.
Definition: private.h:34
const char * desc
Description of pattern.
Definition: private.h:38
int num
Index number.
Definition: private.h:35
const char * expr
Displayed in the menu.
Definition: private.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ greeting_format_str()

static const char* greeting_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a greetings string - Implements format_t -.

Expando Description
%n Recipient's real name (or address if missing)
%u User (login) name of the recipient
%v First name of the recipient

Definition at line 659 of file send.c.

663 {
664  struct Email *e = (struct Email *) data;
665  char *p = NULL;
666  char buf2[256];
667 
668  const struct Address *to = TAILQ_FIRST(&e->env->to);
669  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
670 
671  buf[0] = '\0';
672  switch (op)
673  {
674  case 'n':
675  mutt_format_s(buf, buflen, prec, mutt_get_name(to));
676  break;
677 
678  case 'u':
679  if (to)
680  {
681  mutt_str_copy(buf2, mutt_addr_for_display(to), sizeof(buf2));
682  if ((p = strpbrk(buf2, "%@")))
683  *p = '\0';
684  }
685  else
686  buf2[0] = '\0';
687  mutt_format_s(buf, buflen, prec, buf2);
688  break;
689 
690  case 'v':
691  if (to)
692  mutt_format_s(buf2, sizeof(buf2), prec, mutt_get_name(to));
693  else if (cc)
694  mutt_format_s(buf2, sizeof(buf2), prec, mutt_get_name(cc));
695  else
696  *buf2 = '\0';
697  if ((p = strpbrk(buf2, " %@")))
698  *p = '\0';
699  mutt_format_s(buf, buflen, prec, buf2);
700  break;
701 
702  default:
703  snprintf(buf, buflen, "%%%s%c", prec, op);
704  break;
705  }
706 
707  if (flags & MUTT_FORMAT_OPTIONAL)
708  mutt_expando_format(buf, buflen, col, cols, else_str, greeting_format_str, data, flags);
709 
710  return src;
711 }
static const char * greeting_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a greetings string - Implements format_t -.
Definition: send.c:659
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sidebar_format_str()

static const char* sidebar_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the sidebar - Implements format_t -.

Expando Description
%! 'n!' Flagged messages
%B Name of the mailbox
%D Description of the mailbox
%d Number of deleted messages
%F Number of Flagged messages in the mailbox
%L Number of messages after limiting
%n "N" if mailbox has new mail, " " (space) otherwise
%N Number of unread messages in the mailbox
%o Number of old unread messages in the mailbox
%r Number of read messages in the mailbox
%S Size of mailbox (total number of messages)
%t Number of tagged messages
%Z Number of new unseen messages in the mailbox

Definition at line 346 of file window.c.

350 {
351  struct SidebarFormatData *sfdata = (struct SidebarFormatData *) data;
352  struct SbEntry *sbe = sfdata->entry;
353  struct IndexSharedData *shared = sfdata->shared;
354  char fmt[256];
355 
356  if (!sbe || !shared || !buf)
357  return src;
358 
359  buf[0] = '\0'; /* Just in case there's nothing to do */
360 
361  struct Mailbox *m = sbe->mailbox;
362  if (!m)
363  return src;
364 
365  struct Mailbox *m_cur = shared->mailbox;
366 
367  bool c = m_cur && mutt_str_equal(m_cur->realpath, m->realpath);
368 
369  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
370 
371  switch (op)
372  {
373  case 'B':
374  case 'D':
375  {
376  char indented[256] = { 0 };
377  size_t ilen = sizeof(indented);
378  size_t off = add_indent(indented, ilen, sbe);
379  snprintf(indented + off, ilen - off, "%s",
380  ((op == 'D') && sbe->mailbox->name) ? sbe->mailbox->name : sbe->box);
381  mutt_format_s(buf, buflen, prec, indented);
382  break;
383  }
384 
385  case 'd':
386  if (!optional)
387  {
388  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
389  snprintf(buf, buflen, fmt, c ? m_cur->msg_deleted : 0);
390  }
391  else if ((c && (m_cur->msg_deleted == 0)) || !c)
392  optional = false;
393  break;
394 
395  case 'F':
396  if (!optional)
397  {
398  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
399  snprintf(buf, buflen, fmt, m->msg_flagged);
400  }
401  else if (m->msg_flagged == 0)
402  optional = false;
403  break;
404 
405  case 'L':
406  if (!optional)
407  {
408  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
409  snprintf(buf, buflen, fmt, c ? m_cur->vcount : m->msg_count);
410  }
411  else if ((c && (m_cur->vcount == m->msg_count)) || !c)
412  optional = false;
413  break;
414 
415  case 'N':
416  if (!optional)
417  {
418  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
419  snprintf(buf, buflen, fmt, m->msg_unread);
420  }
421  else if (m->msg_unread == 0)
422  optional = false;
423  break;
424 
425  case 'n':
426  if (!optional)
427  {
428  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
429  snprintf(buf, buflen, fmt, m->has_new ? 'N' : ' ');
430  }
431  else if (m->has_new == false)
432  optional = false;
433  break;
434 
435  case 'o':
436  if (!optional)
437  {
438  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
439  snprintf(buf, buflen, fmt, m->msg_unread - m->msg_new);
440  }
441  else if ((c && (m_cur->msg_unread - m_cur->msg_new) == 0) || !c)
442  optional = false;
443  break;
444 
445  case 'r':
446  if (!optional)
447  {
448  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
449  snprintf(buf, buflen, fmt, m->msg_count - m->msg_unread);
450  }
451  else if ((c && (m_cur->msg_count - m_cur->msg_unread) == 0) || !c)
452  optional = false;
453  break;
454 
455  case 'S':
456  if (!optional)
457  {
458  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
459  snprintf(buf, buflen, fmt, m->msg_count);
460  }
461  else if (m->msg_count == 0)
462  optional = false;
463  break;
464 
465  case 't':
466  if (!optional)
467  {
468  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
469  snprintf(buf, buflen, fmt, c ? m_cur->msg_tagged : 0);
470  }
471  else if ((c && (m_cur->msg_tagged == 0)) || !c)
472  optional = false;
473  break;
474 
475  case 'Z':
476  if (!optional)
477  {
478  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
479  snprintf(buf, buflen, fmt, m->msg_new);
480  }
481  else if ((c && (m_cur->msg_new) == 0) || !c)
482  optional = false;
483  break;
484 
485  case '!':
486  if (m->msg_flagged == 0)
487  mutt_format_s(buf, buflen, prec, "");
488  else if (m->msg_flagged == 1)
489  mutt_format_s(buf, buflen, prec, "!");
490  else if (m->msg_flagged == 2)
491  mutt_format_s(buf, buflen, prec, "!!");
492  else
493  {
494  snprintf(fmt, sizeof(fmt), "%d!", m->msg_flagged);
495  mutt_format_s(buf, buflen, prec, fmt);
496  }
497  break;
498  }
499 
500  if (optional)
501  {
502  mutt_expando_format(buf, buflen, col, cols, if_str, sidebar_format_str, data, flags);
503  }
504  else if (flags & MUTT_FORMAT_OPTIONAL)
505  {
506  mutt_expando_format(buf, buflen, col, cols, else_str, sidebar_format_str, data, flags);
507  }
508 
509  /* We return the format string, unchanged */
510  return src;
511 }
static const char * sidebar_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the sidebar - Implements format_t -.
Definition: window.c:346
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:784
static size_t add_indent(char *buf, size_t buflen, const struct SbEntry *sbe)
Generate the needed indentation.
Definition: window.c:231
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
int vcount
The number of virtual messages.
Definition: mailbox.h:99
bool has_new
Mailbox has new mail.
Definition: mailbox.h:85
int msg_new
Number of new messages.
Definition: mailbox.h:92
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:93
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:90
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:94
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
Info about folders in the sidebar.
Definition: private.h:41
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:45
char box[256]
Mailbox path (possibly abbreviated)
Definition: private.h:42
Data passed to sidebar_format_str()
Definition: window.c:88
struct IndexSharedData * shared
Shared Index Data.
Definition: window.c:90
struct SbEntry * entry
Info about a folder.
Definition: window.c:89
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ status_format_str()

static const char* status_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Create the status bar string - Implements format_t -.

Expando Description
%b Number of incoming folders with unread messages
%D Description of the mailbox
%d Number of deleted messages
%f Full mailbox path
%F Number of flagged messages
%h Hostname
%l Length of mailbox (in bytes)
%L Size (in bytes) of the messages shown (or limited)
%M Number of messages shown (virtual message count when limiting)
%m Total number of messages
%n Number of new messages
%o Number of old unread messages
%p Number of postponed messages
%P Percent of way through index
%R Number of read messages
%r Readonly/wontwrite/changed flag
%S Current aux sorting method ($sort_aux)
%s Current sorting method ($sort)
%T Current threading view ($use_threads)
%t Number of tagged messages
%u Number of unread messages
%V Currently active limit pattern
%v NeoMutt version

Definition at line 101 of file status.c.

105 {
106  char fmt[128], tmp[128];
107  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
108  struct MenuStatusLineData *msld = (struct MenuStatusLineData *) data;
109  struct IndexSharedData *shared = msld->shared;
110  struct MailboxView *mv = shared->mailboxview;
111  struct Mailbox *m = shared->mailbox;
112  struct Menu *menu = msld->menu;
113 
114  *buf = '\0';
115  switch (op)
116  {
117  case 'b':
118  {
120  if (!optional)
121  {
122  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
123  snprintf(buf, buflen, fmt, num);
124  }
125  else if (num == 0)
126  optional = false;
127  break;
128  }
129 
130  case 'd':
131  {
132  const int num = m ? m->msg_deleted : 0;
133  if (!optional)
134  {
135  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
136  snprintf(buf, buflen, fmt, num);
137  }
138  else if (num == 0)
139  optional = false;
140  break;
141  }
142 
143  case 'D':
144  // If there's a descriptive name, use it. Otherwise, fall-through
145  if (m && m->name)
146  {
147  mutt_str_copy(tmp, m->name, sizeof(tmp));
148  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
149  snprintf(buf, buflen, fmt, tmp);
150  break;
151  }
152  /* fallthrough */
153  case 'f':
154 #ifdef USE_COMP_MBOX
155  if (m && m->compress_info && (m->realpath[0] != '\0'))
156  {
157  mutt_str_copy(tmp, m->realpath, sizeof(tmp));
158  mutt_pretty_mailbox(tmp, sizeof(tmp));
159  }
160  else
161 #endif
162  if (m && (m->type == MUTT_NOTMUCH) && m->name)
163  {
164  mutt_str_copy(tmp, m->name, sizeof(tmp));
165  }
166  else if (m && !mutt_buffer_is_empty(&m->pathbuf))
167  {
168  mutt_str_copy(tmp, mailbox_path(m), sizeof(tmp));
169  mutt_pretty_mailbox(tmp, sizeof(tmp));
170  }
171  else
172  mutt_str_copy(tmp, _("(no mailbox)"), sizeof(tmp));
173 
174  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
175  snprintf(buf, buflen, fmt, tmp);
176  break;
177  case 'F':
178  {
179  const int num = m ? m->msg_flagged : 0;
180  if (!optional)
181  {
182  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
183  snprintf(buf, buflen, fmt, num);
184  }
185  else if (num == 0)
186  optional = false;
187  break;
188  }
189 
190  case 'h':
191  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
192  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
193  break;
194 
195  case 'l':
196  {
197  const off_t num = m ? m->size : 0;
198  if (!optional)
199  {
200  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
201  mutt_str_pretty_size(tmp, sizeof(tmp), num);
202  snprintf(buf, buflen, fmt, tmp);
203  }
204  else if (num == 0)
205  optional = false;
206  break;
207  }
208 
209  case 'L':
210  if (!optional)
211  {
212  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
213  mutt_str_pretty_size(tmp, sizeof(tmp), mv ? mv->vsize : 0);
214  snprintf(buf, buflen, fmt, tmp);
215  }
216  else if (!mview_has_limit(mv))
217  optional = false;
218  break;
219 
220  case 'm':
221  {
222  const int num = m ? m->msg_count : 0;
223  if (!optional)
224  {
225  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
226  snprintf(buf, buflen, fmt, num);
227  }
228  else if (num == 0)
229  optional = false;
230  break;
231  }
232 
233  case 'M':
234  if (!optional)
235  {
236  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
237  snprintf(buf, buflen, fmt, m ? m->vcount : 0);
238  }
239  else if (!mview_has_limit(mv))
240  optional = false;
241  break;
242 
243  case 'n':
244  {
245  const int num = m ? m->msg_new : 0;
246  if (!optional)
247  {
248  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
249  snprintf(buf, buflen, fmt, num);
250  }
251  else if (num == 0)
252  optional = false;
253  break;
254  }
255 
256  case 'o':
257  {
258  const int num = m ? (m->msg_unread - m->msg_new) : 0;
259  if (!optional)
260  {
261  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
262  snprintf(buf, buflen, fmt, num);
263  }
264  else if (num == 0)
265  optional = false;
266  break;
267  }
268 
269  case 'p':
270  {
271  const int count = mutt_num_postponed(m, false);
272  if (!optional)
273  {
274  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
275  snprintf(buf, buflen, fmt, count);
276  }
277  else if (count == 0)
278  optional = false;
279  break;
280  }
281 
282  case 'P':
283  {
284  if (!menu)
285  break;
286  char *cp = NULL;
287  if (menu->top + menu->page_len >= menu->max)
288  {
289  cp = menu->top ?
290  /* L10N: Status bar message: the end of the list emails is visible in the index */
291  _("end") :
292  /* L10N: Status bar message: all the emails are visible in the index */
293  _("all");
294  }
295  else
296  {
297  int count = (100 * (menu->top + menu->page_len)) / menu->max;
298  snprintf(tmp, sizeof(tmp), "%d%%", count);
299  cp = tmp;
300  }
301  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
302  snprintf(buf, buflen, fmt, cp);
303  break;
304  }
305 
306  case 'r':
307  {
308  size_t i = 0;
309 
310  if (m)
311  {
312  i = OptAttachMsg ? 3 :
313  ((m->readonly || m->dontwrite) ? 2 :
314  (m->changed ||
315  /* deleted doesn't necessarily mean changed in IMAP */
316  (m->type != MUTT_IMAP && m->msg_deleted)) ?
317  1 :
318  0);
319  }
320 
321  const struct MbTable *c_status_chars = cs_subset_mbtable(NeoMutt->sub, "status_chars");
322  if (!c_status_chars || !c_status_chars->len)
323  buf[0] = '\0';
324  else if (i >= c_status_chars->len)
325  snprintf(buf, buflen, "%s", c_status_chars->chars[0]);
326  else
327  snprintf(buf, buflen, "%s", c_status_chars->chars[i]);
328  break;
329  }
330 
331  case 'R':
332  {
333  const int read = m ? (m->msg_count - m->msg_unread) : 0;
334  if (!optional)
335  {
336  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
337  snprintf(buf, buflen, fmt, read);
338  }
339  else if (read == 0)
340  optional = false;
341  break;
342  }
343 
344  case 's':
345  {
346  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
347  const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
348  snprintf(buf, buflen, fmt, get_sort_str(tmp, sizeof(tmp), c_sort));
349  break;
350  }
351 
352  case 'S':
353  {
354  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
355  const short c_sort_aux = cs_subset_sort(NeoMutt->sub, "sort_aux");
356  snprintf(buf, buflen, fmt, get_sort_str(tmp, sizeof(tmp), c_sort_aux));
357  break;
358  }
359 
360  case 't':
361  {
362  const int num = m ? m->msg_tagged : 0;
363  if (!optional)
364  {
365  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
366  snprintf(buf, buflen, fmt, num);
367  }
368  else if (num == 0)
369  optional = false;
370  break;
371  }
372 
373  case 'T':
374  {
375  const enum UseThreads c_use_threads = mutt_thread_style();
376  if (!optional)
377  {
378  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
379  snprintf(buf, buflen, fmt, get_use_threads_str(c_use_threads));
380  }
381  else if (c_use_threads == UT_FLAT)
382  optional = false;
383  break;
384  }
385 
386  case 'u':
387  if (!optional)
388  {
389  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
390  snprintf(buf, buflen, fmt, m ? m->msg_unread : 0);
391  }
392  else if (!m || (m->msg_unread == 0))
393  optional = false;
394  break;
395 
396  case 'v':
397  snprintf(buf, buflen, "%s", mutt_make_version());
398  break;
399 
400  case 'V':
401  if (!optional)
402  {
403  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
404  snprintf(buf, buflen, fmt, mview_has_limit(mv) ? mv->pattern : "");
405  }
406  else if (!mview_has_limit(mv))
407  optional = false;
408  break;
409 
410  case 0:
411  *buf = '\0';
412  return src;
413 
414  default:
415  snprintf(buf, buflen, "%%%s%c", prec, op);
416  break;
417  }
418 
419  if (optional)
420  {
421  mutt_expando_format(buf, buflen, col, cols, if_str, status_format_str, data,
423  }
424  else if (flags & MUTT_FORMAT_OPTIONAL)
425  {
426  mutt_expando_format(buf, buflen, col, cols, else_str, status_format_str,
427  data, MUTT_FORMAT_NO_FLAGS);
428  }
429 
430  /* We return the format string, unchanged */
431  return src;
432 }
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:522
static const char * status_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Create the status bar string - Implements format_t -.
Definition: status.c:101
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
int mutt_mailbox_check(struct Mailbox *m_cur, CheckStatsFlags flags)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:156
const char * get_use_threads_str(enum UseThreads value)
Convert UseThreads enum to string.
Definition: mutt_thread.c:107
enum UseThreads mutt_thread_style(void)
Which threading style is active?
Definition: mutt_thread.c:89
UseThreads
Which threading style is active, $use_threads.
Definition: mutt_thread.h:83
@ UT_FLAT
Unthreaded.
Definition: mutt_thread.h:85
bool mview_has_limit(const struct MailboxView *mv)
Is a limit active?
Definition: mview.c:433
#define MUTT_MAILBOX_CHECK_NO_FLAGS
No flags are set.
Definition: mxapi.h:74
bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:37
int mutt_num_postponed(struct Mailbox *m, bool force)
Return the number of postponed messages.
Definition: postpone.c:69
static char * get_sort_str(char *buf, size_t buflen, enum SortType method)
Get the sort method as a string.
Definition: status.c:55
struct MailboxView * mailboxview
Current Mailbox view.
Definition: shared_data.h:39
The "current" mailbox.
Definition: mview.h:38
off_t vsize
Size (in bytes) of the messages shown.
Definition: mview.h:39
char * pattern
Limit pattern string.
Definition: mview.h:40
bool changed
Mailbox has been modified.
Definition: mailbox.h:111
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
bool dontwrite
Don't write the mailbox on close.
Definition: mailbox.h:112
off_t size
Size of the Mailbox.
Definition: mailbox.h:84
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:121
bool readonly
Don't allow changes to the mailbox.
Definition: mailbox.h:116
Data for creating a Menu line.
Definition: status.c:67
struct IndexSharedData * shared
Data shared between Index, Pager and Sidebar.
Definition: status.c:68
struct Menu * menu
Current Menu.
Definition: status.c:69
Definition: lib.h:69
int top
Entry that is the top of the current page.
Definition: lib.h:80
int max
Number of entries in the menu.
Definition: lib.h:71
int page_len
Number of entries per screen.
Definition: lib.h:74
+ Here is the call graph for this function:
+ Here is the caller graph for this function: