NeoMutt  2022-04-29-249-gaae397
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:793
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] = { 0 };
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,
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 152 of file dlg_attach.c.

155{
156 char fmt[128] = { 0 };
157 char charset[128] = { 0 };
158 struct AttachPtr *aptr = (struct AttachPtr *) data;
159 bool optional = (flags & MUTT_FORMAT_OPTIONAL);
160
161 switch (op)
162 {
163 case 'C':
164 if (!optional)
165 {
166 if (mutt_is_text_part(aptr->body) &&
167 mutt_body_get_charset(aptr->body, charset, sizeof(charset)))
168 {
169 mutt_format_s(buf, buflen, prec, charset);
170 }
171 else
172 mutt_format_s(buf, buflen, prec, "");
173 }
174 else if (!mutt_is_text_part(aptr->body) ||
175 !mutt_body_get_charset(aptr->body, charset, sizeof(charset)))
176 {
177 optional = false;
178 }
179 break;
180 case 'c':
181 /* XXX */
182 if (!optional)
183 {
184 snprintf(fmt, sizeof(fmt), "%%%sc", prec);
185 snprintf(buf, buflen, fmt,
186 ((aptr->body->type != TYPE_TEXT) || aptr->body->noconv) ? 'n' : 'c');
187 }
188 else if ((aptr->body->type != TYPE_TEXT) || aptr->body->noconv)
189 optional = false;
190 break;
191 case 'd':
192 {
193 const char *const c_message_format = cs_subset_string(NeoMutt->sub, "message_format");
194 if (!optional)
195 {
196 if (aptr->body->description)
197 {
198 mutt_format_s(buf, buflen, prec, aptr->body->description);
199 break;
200 }
201 if (mutt_is_message_type(aptr->body->type, aptr->body->subtype) &&
202 c_message_format && aptr->body->email)
203 {
204 char s[128] = { 0 };
205 mutt_make_string(s, sizeof(s), cols, c_message_format, NULL, -1,
206 aptr->body->email,
208 if (*s)
209 {
210 mutt_format_s(buf, buflen, prec, s);
211 break;
212 }
213 }
214 if (!aptr->body->d_filename && !aptr->body->filename)
215 {
216 mutt_format_s(buf, buflen, prec, "<no description>");
217 break;
218 }
219 }
220 else if (aptr->body->description ||
221 (mutt_is_message_type(aptr->body->type, aptr->body->subtype) &&
222 c_message_format && aptr->body->email))
223 {
224 break;
225 }
226 }
227 /* fallthrough */
228 case 'F':
229 if (!optional)
230 {
231 if (aptr->body->d_filename)
232 {
233 mutt_format_s(buf, buflen, prec, aptr->body->d_filename);
234 break;
235 }
236 }
237 else if (!aptr->body->d_filename && !aptr->body->filename)
238 {
239 optional = false;
240 break;
241 }
242 /* fallthrough */
243 case 'f':
244 if (!optional)
245 {
246 if (aptr->body->filename && (*aptr->body->filename == '/'))
247 {
248 struct Buffer *path = mutt_buffer_pool_get();
249
250 mutt_buffer_strcpy(path, aptr->body->filename);
252 mutt_format_s(buf, buflen, prec, mutt_buffer_string(path));
254 }
255 else
256 mutt_format_s(buf, buflen, prec, NONULL(aptr->body->filename));
257 }
258 else if (!aptr->body->filename)
259 optional = false;
260 break;
261 case 'D':
262 if (!optional)
263 snprintf(buf, buflen, "%c", aptr->body->deleted ? 'D' : ' ');
264 else if (!aptr->body->deleted)
265 optional = false;
266 break;
267 case 'e':
268 if (!optional)
269 mutt_format_s(buf, buflen, prec, ENCODING(aptr->body->encoding));
270 break;
271 case 'I':
272 if (optional)
273 break;
274
275 const char dispchar[] = { 'I', 'A', 'F', '-' };
276 char ch;
277
278 if (aptr->body->disposition < sizeof(dispchar))
279 ch = dispchar[aptr->body->disposition];
280 else
281 {
282 mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n",
283 aptr->body->disposition);
284 ch = '!';
285 }
286 snprintf(buf, buflen, "%c", ch);
287 break;
288 case 'm':
289 if (!optional)
290 mutt_format_s(buf, buflen, prec, TYPE(aptr->body));
291 break;
292 case 'M':
293 if (!optional)
294 mutt_format_s(buf, buflen, prec, aptr->body->subtype);
295 else if (!aptr->body->subtype)
296 optional = false;
297 break;
298 case 'n':
299 if (optional)
300 break;
301
302 snprintf(fmt, sizeof(fmt), "%%%sd", prec);
303 snprintf(buf, buflen, fmt, aptr->num + 1);
304 break;
305 case 'Q':
306 if (optional)
307 optional = aptr->body->attach_qualifies;
308 else
309 {
310 snprintf(fmt, sizeof(fmt), "%%%sc", prec);
311 mutt_format_s(buf, buflen, fmt, "Q");
312 }
313 break;
314 case 's':
315 {
316 size_t l = 0;
317 if (aptr->body->filename && (flags & MUTT_FORMAT_STAT_FILE))
318 {
319 l = mutt_file_get_size(aptr->body->filename);
320 }
321 else
322 l = aptr->body->length;
323
324 if (!optional)
325 {
326 char tmp[128] = { 0 };
327 mutt_str_pretty_size(tmp, sizeof(tmp), l);
328 mutt_format_s(buf, buflen, prec, tmp);
329 }
330 else if (l == 0)
331 optional = false;
332
333 break;
334 }
335 case 't':
336 if (!optional)
337 snprintf(buf, buflen, "%c", aptr->body->tagged ? '*' : ' ');
338 else if (!aptr->body->tagged)
339 optional = false;
340 break;
341 case 'T':
342 if (!optional)
343 mutt_format_s_tree(buf, buflen, prec, NONULL(aptr->tree));
344 else if (!aptr->tree)
345 optional = false;
346 break;
347 case 'u':
348 if (!optional)
349 snprintf(buf, buflen, "%c", aptr->body->unlink ? '-' : ' ');
350 else if (!aptr->body->unlink)
351 optional = false;
352 break;
353 case 'X':
354 if (optional)
355 optional = ((aptr->body->attach_count + aptr->body->attach_qualifies) != 0);
356 else
357 {
358 snprintf(fmt, sizeof(fmt), "%%%sd", prec);
359 snprintf(buf, buflen, fmt, aptr->body->attach_count + aptr->body->attach_qualifies);
360 }
361 break;
362 default:
363 *buf = '\0';
364 }
365
366 if (optional)
367 {
368 mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data,
370 }
371 else if (flags & MUTT_FORMAT_OPTIONAL)
372 {
373 mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str,
375 }
376
377 /* We return the format string, unchanged */
378 return src;
379}
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
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:805
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:152
#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:1441
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] = { 0 };
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] = { 0 };
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] = { 0 };
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] = { 0 };
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,
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:692
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:428
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
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:210
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 == '(')
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,
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':
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] = { 0 };
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;
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 {
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 &&
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(const struct Mailbox *m, struct Email *e, FILE *fp)
Count the MIME Body parts.
Definition: attachments.c:251
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
@ MT_COLOR_INDEX_AUTHOR
Index: author field.
Definition: color.h:78
@ MT_COLOR_INDEX_SIZE
Index: size field.
Definition: color.h:84
@ MT_COLOR_INDEX_TAGS
Index: tags field (g, J)
Definition: color.h:87
@ MT_COLOR_INDEX_SUBJECT
Index: subject field.
Definition: color.h:85
@ MT_COLOR_INDEX_DATE
Index: date field.
Definition: color.h:80
@ MT_COLOR_INDEX_TAG
Index: tag field (G)
Definition: color.h:86
@ MT_COLOR_INDEX_LABEL
Index: label field.
Definition: color.h:82
@ MT_COLOR_INDEX
Index: default colour.
Definition: color.h:77
@ MT_COLOR_INDEX_NUMBER
Index: index number.
Definition: color.h:83
@ MT_COLOR_INDEX_FLAGS
Index: flags field.
Definition: color.h:81
@ MT_COLOR_INDEX_COLLAPSED
Index: number of messages in collapsed thread.
Definition: color.h:79
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:756
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:655
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone.
Definition: date.c:673
#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 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 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_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:954
@ 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:819
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:431
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:652
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:1469
#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:125
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:123
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(struct TagList *list)
Get transformed tags.
Definition: tags.c:133
struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: tags.c:39
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
+ 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] = { 0 };
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] = { 0 };
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';
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
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:67
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:248
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
void mutt_buffer_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
Definition: buffer.c:483
#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:858
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:907
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:567
#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] = { 0 };
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,
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:138
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] = { 0 };
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,
484 }
485 else if (flags & MUTT_FORMAT_OPTIONAL)
486 {
487 mutt_expando_format(buf, buflen, col, cols, else_str, pgp_entry_format_str,
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] = { 0 };
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,
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] = { 0 };
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:168
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 925 of file newsrc.c.

928{
929 struct NntpAccountData *adata = (struct NntpAccountData *) data;
930 struct ConnAccount *cac = &adata->conn->account;
931 char fn[128], fmt[128];
932
933 switch (op)
934 {
935 case 'a':
936 {
937 struct Url url = { 0 };
938 mutt_account_tourl(cac, &url);
939 url_tostring(&url, fn, sizeof(fn), U_PATH);
940 char *p = strchr(fn, '/');
941 if (p)
942 *p = '\0';
943 snprintf(fmt, sizeof(fmt), "%%%ss", prec);
944 snprintf(buf, buflen, fmt, fn);
945 break;
946 }
947 case 'p':
948 snprintf(fmt, sizeof(fmt), "%%%su", prec);
949 snprintf(buf, buflen, fmt, cac->port);
950 break;
951 case 'P':
952 *buf = '\0';
953 if (cac->flags & MUTT_ACCT_PORT)
954 {
955 snprintf(fmt, sizeof(fmt), "%%%su", prec);
956 snprintf(buf, buflen, fmt, cac->port);
957 }
958 break;
959 case 's':
960 mutt_str_copy(fn, cac->host, sizeof(fn));
961 mutt_str_lower(fn);
962 snprintf(fmt, sizeof(fmt), "%%%ss", prec);
963 snprintf(buf, buflen, fmt, fn);
964 break;
965 case 'S':
966 {
967 struct Url url = { 0 };
968 mutt_account_tourl(cac, &url);
969 url_tostring(&url, fn, sizeof(fn), U_PATH);
970 char *p = strchr(fn, ':');
971 if (p)
972 *p = '\0';
973 snprintf(fmt, sizeof(fmt), "%%%ss", prec);
974 snprintf(buf, buflen, fmt, fn);
975 break;
976 }
977 case 'u':
978 snprintf(fmt, sizeof(fmt), "%%%ss", prec);
979 snprintf(buf, buflen, fmt, cac->user);
980 break;
981 }
982 return src;
983}
#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] = { 0 };
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] = { 0 };
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:807
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,
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:435
#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:110
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
bool dontwrite
Don't write the mailbox on close.
Definition: mailbox.h:111
off_t size
Size of the Mailbox.
Definition: mailbox.h:84
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:120
bool readonly
Don't allow changes to the mailbox.
Definition: mailbox.h:115
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: