NeoMutt  2024-11-14-138-ge5ca67
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
expando.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <grp.h>
31#include <pwd.h>
32#include <stdbool.h>
33#include <stdio.h>
34#include <sys/stat.h>
35#include <time.h>
36#include "mutt/lib.h"
37#include "config/lib.h"
38#include "core/lib.h"
39#include "expando.h"
40#include "lib.h"
41#include "expando/lib.h"
42#include "muttlib.h"
43
47static void folder_date(const struct ExpandoNode *node, void *data,
48 MuttFormatFlags flags, struct Buffer *buf)
49{
50 const struct Folder *folder = data;
51 if (!folder->ff->local)
52 return;
53
54 static const time_t one_year = 31536000;
55 const char *t_fmt = ((mutt_date_now() - folder->ff->mtime) < one_year) ?
56 "%b %d %H:%M" :
57 "%b %d %Y";
58
59 char tmp[128] = { 0 };
60
61 mutt_date_localtime_format(tmp, sizeof(tmp), t_fmt, folder->ff->mtime);
62
63 buf_strcpy(buf, tmp);
64}
65
69static long folder_date_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
70{
71 const struct Folder *folder = data;
72 if (!folder->ff->local)
73 return 0;
74
75 return folder->ff->mtime;
76}
77
81static void folder_date_format(const struct ExpandoNode *node, void *data,
82 MuttFormatFlags flags, struct Buffer *buf)
83{
84 const struct Folder *folder = data;
85 if (!folder->ff->local)
86 return;
87
88 char tmp[128] = { 0 };
89 bool use_c_locale = false;
90 const char *const c_date_format = cs_subset_string(NeoMutt->sub, "date_format");
91 const char *t_fmt = NONULL(c_date_format);
92 if (*t_fmt == '!')
93 {
94 t_fmt++;
95 use_c_locale = true;
96 }
97
98 if (use_c_locale)
99 {
100 mutt_date_localtime_format_locale(tmp, sizeof(tmp), t_fmt,
101 folder->ff->mtime, NeoMutt->time_c_locale);
102 }
103 else
104 {
105 mutt_date_localtime_format(tmp, sizeof(tmp), t_fmt, folder->ff->mtime);
106 }
107
108 buf_strcpy(buf, tmp);
109}
110
114static long folder_date_format_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
115{
116 const struct Folder *folder = data;
117 if (!folder->ff->local)
118 return 0;
119
120 return folder->ff->mtime;
121}
122
126static void folder_date_strf(const struct ExpandoNode *node, void *data,
127 MuttFormatFlags flags, struct Buffer *buf)
128{
129 const struct Folder *folder = data;
130
131 if (!folder->ff->local)
132 return;
133
134 bool use_c_locale = false;
135 const char *text = node->text;
136 if (*text == '!')
137 {
138 use_c_locale = true;
139 text++;
140 }
141
142 char tmp[128] = { 0 };
143 struct tm tm = mutt_date_localtime(folder->ff->mtime);
144
145 if (use_c_locale)
146 {
147 strftime_l(tmp, sizeof(tmp), text, &tm, NeoMutt->time_c_locale);
148 }
149 else
150 {
151 strftime(tmp, sizeof(tmp), text, &tm);
152 }
153
154 buf_strcpy(buf, tmp);
155}
156
160static long folder_date_strf_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
161{
162 const struct Folder *folder = data;
163
164 if (!folder->ff->local)
165 return 0;
166
167 return folder->ff->mtime;
168}
169
173static void folder_description(const struct ExpandoNode *node, void *data,
174 MuttFormatFlags flags, struct Buffer *buf)
175{
176 const struct Folder *folder = data;
177
178 const char *s = NULL;
179 if (folder->ff->desc)
180 s = folder->ff->desc;
181 else
182 s = folder->ff->name;
183
184 buf_printf(buf, "%s%s", s,
185 folder->ff->local ?
186 (S_ISLNK(folder->ff->mode) ?
187 "@" :
188 (S_ISDIR(folder->ff->mode) ?
189 "/" :
190 (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
191 "");
192}
193
197static void folder_filename(const struct ExpandoNode *node, void *data,
198 MuttFormatFlags flags, struct Buffer *buf)
199{
200 const struct Folder *folder = data;
201
202 const char *s = NONULL(folder->ff->name);
203
204 buf_printf(buf, "%s%s", s,
205 folder->ff->local ?
206 (S_ISLNK(folder->ff->mode) ?
207 "@" :
208 (S_ISDIR(folder->ff->mode) ?
209 "/" :
210 (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
211 "");
212}
213
217static void folder_file_group(const struct ExpandoNode *node, void *data,
218 MuttFormatFlags flags, struct Buffer *buf)
219{
220 const struct Folder *folder = data;
221 if (!folder->ff->local)
222 return;
223
224 struct group *gr = getgrgid(folder->ff->gid);
225 if (gr)
226 {
227 buf_addstr(buf, gr->gr_name);
228 }
229 else
230 {
231 buf_printf(buf, "%u", folder->ff->gid);
232 }
233}
234
238static void folder_file_mode(const struct ExpandoNode *node, void *data,
239 MuttFormatFlags flags, struct Buffer *buf)
240{
241 const struct Folder *folder = data;
242
243 if (folder->ff->local)
244 {
245 buf_printf(buf, "%c%c%c%c%c%c%c%c%c%c",
246 S_ISDIR(folder->ff->mode) ? 'd' : (S_ISLNK(folder->ff->mode) ? 'l' : '-'),
247 ((folder->ff->mode & S_IRUSR) != 0) ? 'r' : '-',
248 ((folder->ff->mode & S_IWUSR) != 0) ? 'w' : '-',
249 ((folder->ff->mode & S_ISUID) != 0) ? 's' :
250 ((folder->ff->mode & S_IXUSR) != 0) ? 'x' :
251 '-',
252 ((folder->ff->mode & S_IRGRP) != 0) ? 'r' : '-',
253 ((folder->ff->mode & S_IWGRP) != 0) ? 'w' : '-',
254 ((folder->ff->mode & S_ISGID) != 0) ? 's' :
255 ((folder->ff->mode & S_IXGRP) != 0) ? 'x' :
256 '-',
257 ((folder->ff->mode & S_IROTH) != 0) ? 'r' : '-',
258 ((folder->ff->mode & S_IWOTH) != 0) ? 'w' : '-',
259 ((folder->ff->mode & S_ISVTX) != 0) ? 't' :
260 ((folder->ff->mode & S_IXOTH) != 0) ? 'x' :
261 '-');
262 }
263 else if (folder->ff->imap)
264 {
265 /* mark folders with subfolders AND mail */
266 buf_printf(buf, "IMAP %c", (folder->ff->inferiors && folder->ff->selectable) ? '+' : ' ');
267 }
268}
269
273static void folder_file_owner(const struct ExpandoNode *node, void *data,
274 MuttFormatFlags flags, struct Buffer *buf)
275{
276 const struct Folder *folder = data;
277 if (!folder->ff->local)
278 return;
279
280 struct passwd *pw = getpwuid(folder->ff->uid);
281 if (pw)
282 {
283 buf_addstr(buf, pw->pw_name);
284 }
285 else
286 {
287 buf_printf(buf, "%u", folder->ff->uid);
288 }
289}
290
294static void folder_file_size(const struct ExpandoNode *node, void *data,
295 MuttFormatFlags flags, struct Buffer *buf)
296{
297 const struct Folder *folder = data;
298
299 char tmp[128] = { 0 };
300
301 mutt_str_pretty_size(tmp, sizeof(tmp), folder->ff->size);
302 buf_strcpy(buf, tmp);
303}
304
308static long folder_file_size_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
309{
310 const struct Folder *folder = data;
311 return folder->ff->size;
312}
313
317static void folder_hard_links(const struct ExpandoNode *node, void *data,
318 MuttFormatFlags flags, struct Buffer *buf)
319{
320 const struct Folder *folder = data;
321 if (!folder->ff->local)
322 return;
323
324 buf_add_printf(buf, "%d", (int) folder->ff->nlink);
325}
326
330static long folder_hard_links_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
331{
332 const struct Folder *folder = data;
333
334 if (folder->ff->local)
335 return folder->ff->nlink;
336
337 return 0;
338}
339
343static void folder_message_count(const struct ExpandoNode *node, void *data,
344 MuttFormatFlags flags, struct Buffer *buf)
345{
346 const struct Folder *folder = data;
347 if (!folder->ff->has_mailbox)
348 return;
349
350 buf_add_printf(buf, "%d", folder->ff->msg_count);
351}
352
356static long folder_message_count_num(const struct ExpandoNode *node, void *data,
357 MuttFormatFlags flags)
358{
359 const struct Folder *folder = data;
360
361 if (folder->ff->has_mailbox)
362 return folder->ff->msg_count;
363
364 return 0;
365}
366
370static void folder_new_mail(const struct ExpandoNode *node, void *data,
371 MuttFormatFlags flags, struct Buffer *buf)
372{
373 const struct Folder *folder = data;
374
375 // NOTE(g0mb4): use $to_chars?
376 const char *s = folder->ff->has_new_mail ? "N" : " ";
377 buf_strcpy(buf, s);
378}
379
383static long folder_new_mail_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
384{
385 const struct Folder *folder = data;
386 return folder->ff->has_new_mail;
387}
388
392static long folder_notify_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
393{
394 const struct Folder *folder = data;
395
396 return folder->ff->notify_user;
397}
398
402static long folder_number_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
403{
404 const struct Folder *folder = data;
405
406 return folder->num + 1;
407}
408
412static long folder_poll_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
413{
414 const struct Folder *folder = data;
415
416 return folder->ff->poll_new_mail;
417}
418
422static void folder_tagged(const struct ExpandoNode *node, void *data,
423 MuttFormatFlags flags, struct Buffer *buf)
424{
425 const struct Folder *folder = data;
426
427 // NOTE(g0mb4): use $to_chars?
428 const char *s = folder->ff->tagged ? "*" : " ";
429 buf_strcpy(buf, s);
430}
431
435static long folder_tagged_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
436{
437 const struct Folder *folder = data;
438 return folder->ff->tagged;
439}
440
444static void folder_unread_count(const struct ExpandoNode *node, void *data,
445 MuttFormatFlags flags, struct Buffer *buf)
446{
447 const struct Folder *folder = data;
448 if (!folder->ff->has_mailbox)
449 return;
450
451 buf_add_printf(buf, "%d", folder->ff->msg_unread);
452}
453
457static long folder_unread_count_num(const struct ExpandoNode *node, void *data,
458 MuttFormatFlags flags)
459{
460 const struct Folder *folder = data;
461
462 if (folder->ff->has_mailbox)
463 return folder->ff->msg_unread;
464
465 return 0;
466}
467
471static void global_padding_space(const struct ExpandoNode *node, void *data,
472 MuttFormatFlags flags, struct Buffer *buf)
473{
474 buf_addstr(buf, " ");
475}
476
483 // clang-format off
502 { -1, -1, NULL, NULL },
503 // clang-format on
504};
const struct ExpandoRenderCallback FolderRenderCallbacks[]
Callbacks for Browser Expandos.
Definition: expando.c:482
@ ED_FOL_POLL
FolderFile.poll_new_mail.
Definition: lib.h:135
@ ED_FOL_NOTIFY
FolderFile.notify_user.
Definition: lib.h:133
@ ED_FOL_FILE_OWNER
FolderFile.uid.
Definition: lib.h:124
@ ED_FOL_FILE_GROUP
FolderFile.gid.
Definition: lib.h:122
@ ED_FOL_FILENAME
FolderFile.name.
Definition: lib.h:121
@ ED_FOL_DATE_FORMAT
FolderFile.mtime.
Definition: lib.h:118
@ ED_FOL_DATE_STRF
FolderFile.mtime.
Definition: lib.h:119
@ ED_FOL_UNREAD_COUNT
FolderFile.msg_unread.
Definition: lib.h:137
@ ED_FOL_FILE_MODE
FolderFile.move.
Definition: lib.h:123
@ ED_FOL_NEW_MAIL
FolderFile.has_new_mail.
Definition: lib.h:132
@ ED_FOL_FILE_SIZE
FolderFile.size.
Definition: lib.h:125
@ ED_FOL_HARD_LINKS
FolderFile.nlink.
Definition: lib.h:128
@ ED_FOL_DATE
FolderFile.mtime.
Definition: lib.h:117
@ ED_FOL_TAGGED
FolderFile.tagged.
Definition: lib.h:136
@ ED_FOL_NUMBER
Folder.num.
Definition: lib.h:134
@ ED_FOL_DESCRIPTION
FolderFile.desc, FolderFile.name.
Definition: lib.h:120
@ ED_FOL_MESSAGE_COUNT
FolderFile.msg_count.
Definition: lib.h:129
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:204
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
@ ED_FOLDER
Folder ED_FOL_ ExpandoDataFolder.
Definition: domain.h:43
@ ED_GLOBAL
Global ED_GLO_ ExpandoDataGlobal.
Definition: domain.h:44
Parse Expando string.
static long folder_date_strf_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Last modified (strftime) - Implements get_number_t -.
Definition: expando.c:160
static long folder_message_count_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Number of messages - Implements get_number_t -.
Definition: expando.c:356
static long folder_file_size_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Size in bytes - Implements get_number_t -.
Definition: expando.c:308
static long folder_hard_links_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Hard links - Implements get_number_t -.
Definition: expando.c:330
static long folder_number_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Index number - Implements get_number_t -.
Definition: expando.c:402
static long folder_new_mail_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: New mail flag - Implements get_number_t -.
Definition: expando.c:383
static long folder_tagged_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Is Tagged - Implements get_number_t -.
Definition: expando.c:435
static long folder_notify_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Alert for new mail - Implements get_number_t -.
Definition: expando.c:392
static long folder_poll_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Poll for new mail - Implements get_number_t -.
Definition: expando.c:412
static long folder_date_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Last modified - Implements get_number_t -.
Definition: expando.c:69
static long folder_unread_count_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Number of unread messages - Implements get_number_t -.
Definition: expando.c:457
static long folder_date_format_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Browser: Last modified ($date_format) - Implements get_number_t -.
Definition: expando.c:114
static void folder_new_mail(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: New mail flag - Implements get_string_t -.
Definition: expando.c:370
static void folder_tagged(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Is Tagged - Implements get_string_t -.
Definition: expando.c:422
static void folder_description(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Description - Implements get_string_t -.
Definition: expando.c:173
static void folder_date_strf(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Last modified (strftime) - Implements get_string_t -.
Definition: expando.c:126
static void folder_date(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Last modified - Implements get_string_t -.
Definition: expando.c:47
static void folder_file_mode(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: File permissions - Implements get_string_t -.
Definition: expando.c:238
static void folder_date_format(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Last modified ($date_format) - Implements get_string_t -.
Definition: expando.c:81
static void folder_file_group(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Group name - Implements get_string_t -.
Definition: expando.c:217
static void folder_file_size(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Size in bytes - Implements get_string_t -.
Definition: expando.c:294
static void global_padding_space(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Fixed whitespace - Implements get_string_t -.
Definition: expando.c:471
static void folder_filename(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Filename - Implements get_string_t -.
Definition: expando.c:197
static void folder_hard_links(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Hard links - Implements get_string_t -.
Definition: expando.c:317
static void folder_file_owner(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Owner name - Implements get_string_t -.
Definition: expando.c:273
static void folder_message_count(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Number of messages - Implements get_string_t -.
Definition: expando.c:343
static void folder_unread_count(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Browser: Number of unread messages - Implements get_string_t -.
Definition: expando.c:444
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:906
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:951
size_t mutt_date_localtime_format_locale(char *buf, size_t buflen, const char *format, time_t t, locale_t loc)
Format localtime using a given locale.
Definition: date.c:969
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:456
Convenience wrapper for the library headers.
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1004
Some miscellaneous functions.
uint8_t MuttFormatFlags
Flags for expando_render(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: render.h:32
Sidebar Expando definitions.
Key value store.
#define NONULL(x)
Definition: string2.h:37
String manipulation buffer.
Definition: buffer.h:36
Basic Expando Node.
Definition: node.h:67
const char * text
Node-specific text.
Definition: node.h:73
bool selectable
Folder can be selected.
Definition: lib.h:96
bool imap
This is an IMAP folder.
Definition: lib.h:95
bool has_mailbox
This is a mailbox.
Definition: lib.h:98
char * name
Name of file/dir/mailbox.
Definition: lib.h:86
uid_t uid
File's User ID.
Definition: lib.h:82
bool tagged
Folder is tagged.
Definition: lib.h:102
gid_t gid
File's Group ID.
Definition: lib.h:83
bool has_new_mail
true if mailbox has "new mail"
Definition: lib.h:89
bool poll_new_mail
Check mailbox for new mail.
Definition: lib.h:101
bool notify_user
User will be notified of new mail.
Definition: lib.h:100
nlink_t nlink
Number of hard links.
Definition: lib.h:84
char * desc
Description of mailbox.
Definition: lib.h:87
off_t size
File size.
Definition: lib.h:80
time_t mtime
Modification time.
Definition: lib.h:81
int msg_count
total number of messages
Definition: lib.h:90
mode_t mode
File permissions.
Definition: lib.h:79
bool inferiors
Folder has children.
Definition: lib.h:97
int msg_unread
number of unread messages
Definition: lib.h:91
A folder/dir in the browser.
Definition: lib.h:69
int num
Number in the index.
Definition: lib.h:71
struct FolderFile * ff
File / Dir / Mailbox.
Definition: lib.h:70
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
locale_t time_c_locale
Current locale but LC_TIME=C.
Definition: neomutt.h:48
@ ED_GLO_PADDING_SPACE
Space Padding.
Definition: uid.h:41