NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
Compose Function API

Prototype for a Compose Function. More...

+ Collaboration diagram for Compose Function API:

Functions

static int op_attach_attach_file (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Attach files to this message - Implements compose_function_t -.
 
static int op_attach_attach_key (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Attach a PGP public key - Implements compose_function_t -.
 
static int op_attach_attach_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Attach messages to this message - Implements compose_function_t -.
 
static int op_attach_detach (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Delete the current entry - Implements compose_function_t -.
 
static int op_attach_edit_content_id (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the 'Content-ID' of the attachment - Implements compose_function_t -.
 
static int op_attach_edit_description (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment description - Implements compose_function_t -.
 
static int op_attach_edit_encoding (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment transfer-encoding - Implements compose_function_t -.
 
static int op_attach_edit_language (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the 'Content-Language' of the attachment - Implements compose_function_t -.
 
static int op_attach_edit_mime (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment using mailcap entry - Implements compose_function_t -.
 
static int op_attach_edit_type (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment content type - Implements compose_function_t -.
 
static int op_attach_filter (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Filter attachment through a shell command - Implements compose_function_t -.
 
static int op_attach_get_attachment (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Get a temporary copy of an attachment - Implements compose_function_t -.
 
static int op_attach_group_alts (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Group selected attachments as 'multipart/alternative' - Implements compose_function_t -.
 
static int op_attach_group_lingual (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Group selected attachments as 'multipart/multilingual' - Implements compose_function_t -.
 
static int op_attach_group_related (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Group selected attachments as 'multipart/related' - Implements compose_function_t -.
 
static int op_attach_move_down (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Move an attachment down in the attachment list - Implements compose_function_t -.
 
static int op_attach_move_up (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Move an attachment up in the attachment list - Implements compose_function_t -.
 
static int op_attach_new_mime (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Compose new attachment using mailcap entry - Implements compose_function_t -.
 
static int op_attach_print (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Print the current entry - Implements compose_function_t -.
 
static int op_attach_rename_attachment (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Send attachment with a different name - Implements compose_function_t -.
 
static int op_attach_save (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Save message/attachment to a mailbox/file - Implements compose_function_t -.
 
static int op_attach_toggle_disposition (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Toggle disposition between inline/attachment - Implements compose_function_t -.
 
static int op_attach_toggle_recode (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Toggle recoding of this attachment - Implements compose_function_t -.
 
static int op_attach_toggle_unlink (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Toggle whether to delete file after sending it - Implements compose_function_t -.
 
static int op_attach_ungroup (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Ungroup a 'multipart' attachment - Implements compose_function_t -.
 
static int op_attach_update_encoding (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Update an attachment's encoding info - Implements compose_function_t -.
 
static int op_envelope_edit_headers (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the message with headers - Implements compose_function_t -.
 
static int op_compose_edit_file (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the file to be attached - Implements compose_function_t -.
 
static int op_compose_edit_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the message - Implements compose_function_t -.
 
static int op_compose_ispell (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Run ispell on the message - Implements compose_function_t -.
 
static int op_compose_postpone_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Save this message to send later - Implements compose_function_t -.
 
static int op_compose_rename_file (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Rename/move an attached file - Implements compose_function_t -.
 
static int op_compose_send_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Send the message - Implements compose_function_t -.
 
static int op_compose_write_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Write the message to a folder - Implements compose_function_t -.
 
static int op_display_headers (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Display message and toggle header weeding - Implements compose_function_t -.
 
static int op_exit (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Exit this menu - Implements compose_function_t -.
 
static int op_forget_passphrase (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Wipe passphrases from memory - Implements compose_function_t -.
 

Detailed Description

Prototype for a Compose Function.

Parameters
fdataCompose Function context data
eventEvent to process
Return values
enumFunctionRetval
Precondition
fdata is not NULL
event is not NULL

Function Documentation

◆ op_attach_attach_file()

static int op_attach_attach_file ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Attach files to this message - Implements compose_function_t -.

Definition at line 992 of file functions.c.

993{
994 struct ComposeSharedData *shared = fdata->shared;
995 char *prompt = _("Attach file");
996 int numfiles = 0;
997 char **files = NULL;
998
999 struct Buffer *fname = buf_pool_get();
1000 if ((mw_enter_fname(prompt, fname, false, NULL, true, &files, &numfiles,
1001 MUTT_SEL_MULTI) == -1) ||
1002 buf_is_empty(fname))
1003 {
1004 for (int i = 0; i < numfiles; i++)
1005 FREE(&files[i]);
1006
1007 FREE(&files);
1008 buf_pool_release(&fname);
1009 return FR_NO_ACTION;
1010 }
1011
1012 bool error = false;
1013 bool added_attachment = false;
1014 if (numfiles > 1)
1015 {
1016 mutt_message(ngettext("Attaching selected file...",
1017 "Attaching selected files...", numfiles));
1018 }
1019 for (int i = 0; i < numfiles; i++)
1020 {
1021 char *att = files[i];
1022 if (!att)
1023 continue;
1024
1025 struct AttachPtr *ap = mutt_aptr_new();
1026 ap->unowned = true;
1027 ap->body = mutt_make_file_attach(att, shared->sub);
1028 if (ap->body)
1029 {
1030 added_attachment = true;
1031 update_idx(shared->adata->menu, shared->adata->actx, ap);
1032 }
1033 else
1034 {
1035 error = true;
1036 mutt_error(_("Unable to attach %s"), att);
1037 mutt_aptr_free(&ap);
1038 }
1039 FREE(&files[i]);
1040 }
1041
1042 FREE(&files);
1043 buf_pool_release(&fname);
1044
1045 if (!error)
1047
1050 if (added_attachment)
1051 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1052 return added_attachment ? FR_SUCCESS : (error ? FR_ERROR : FR_NO_ACTION);
1053}
struct AttachPtr * mutt_aptr_new(void)
Create a new Attachment Pointer.
Definition attach.c:40
void mutt_aptr_free(struct AttachPtr **ptr)
Free an Attachment Pointer.
Definition attach.c:49
@ MUTT_SEL_MULTI
Multi-selection is enabled.
Definition lib.h:61
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
@ CMD_SEND2_HOOK
:send2-hook
Definition command.h:109
static void update_idx(struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
Add a new attachment to the message.
Definition functions.c:462
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
@ FR_NO_ACTION
Valid function - no action performed.
Definition dispatcher.h:38
@ NT_EMAIL_CHANGE_ATTACH
Email's Attachments have changed.
Definition email.h:188
int mw_enter_fname(const char *prompt, struct Buffer *fname, bool mailbox, struct Mailbox *m, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file -.
Definition curs_lib.c:238
#define mutt_error(...)
Definition logging2.h:94
#define mutt_message(...)
Definition logging2.h:93
void exec_message_hook(struct Mailbox *m, struct Email *e, enum CommandId id)
Perform a message hook.
Definition exec.c:137
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition menu.c:179
@ MENU_REDRAW_INDEX
Redraw the index.
Definition lib.h:61
#define _(a)
Definition message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
@ NT_EMAIL
Email has changed, NotifyEmail, EventEmail.
Definition notify_type.h:44
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition sendlib.c:613
An email to which things will be attached.
Definition attach.h:36
struct Body * body
Attachment.
Definition attach.h:37
bool unowned
Don't unlink on detach.
Definition attach.h:43
String manipulation buffer.
Definition buffer.h:36
struct Menu * menu
Menu displaying the attachments.
Definition attach_data.h:35
struct AttachCtx * actx
Set of attachments.
Definition attach_data.h:34
struct ComposeSharedData * shared
Shared Compose data.
Definition functions.h:36
Shared Compose Data.
Definition shared_data.h:35
struct ConfigSubset * sub
Config set to use.
Definition shared_data.h:36
struct ComposeAttachData * adata
Attachments.
Definition shared_data.h:39
struct Email * email
Email being composed.
Definition shared_data.h:38
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition email.h:73
+ Here is the call graph for this function:

◆ op_attach_attach_key()

static int op_attach_attach_key ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Attach a PGP public key - Implements compose_function_t -.

Definition at line 1058 of file functions.c.

1059{
1060 struct ComposeSharedData *shared = fdata->shared;
1061 if (!(WithCrypto & APPLICATION_PGP))
1062 return FR_NOT_IMPL;
1063 struct AttachPtr *ap = mutt_aptr_new();
1065 if (ap->body)
1066 {
1067 update_idx(shared->adata->menu, shared->adata->actx, ap);
1069 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1070 }
1071 else
1072 {
1073 mutt_aptr_free(&ap);
1074 }
1075
1077 return FR_SUCCESS;
1078}
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition cryptglue.c:349
@ FR_NOT_IMPL
Invalid function - feature not enabled.
Definition dispatcher.h:37
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:106
#define WithCrypto
Definition lib.h:132
+ Here is the call graph for this function:

◆ op_attach_attach_message()

static int op_attach_attach_message ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Attach messages to this message - Implements compose_function_t -.

This function handles:

  • OP_ATTACH_ATTACH_MESSAGE
  • OP_ATTACH_ATTACH_NEWS_MESSAGE

Definition at line 1087 of file functions.c.

1089{
1091 struct ComposeSharedData *shared = fdata->shared;
1092 char *prompt = _("Open mailbox to attach message from");
1093
1094 OptNews = false;
1095 const int op = event->op;
1096 if (shared->mailbox && (op == OP_ATTACH_ATTACH_NEWS_MESSAGE))
1097 {
1098 const char *const c_news_server = cs_subset_string(shared->sub, "news_server");
1099 mod_data->current_news_srv = nntp_select_server(shared->mailbox, c_news_server, false);
1100 if (!mod_data->current_news_srv)
1101 return FR_NO_ACTION;
1102
1103 prompt = _("Open newsgroup to attach message from");
1104 OptNews = true;
1105 }
1106
1107 struct Buffer *fname = buf_pool_get();
1108 if (shared->mailbox)
1109 {
1110 if ((op == OP_ATTACH_ATTACH_MESSAGE) ^ (shared->mailbox->type == MUTT_NNTP))
1111 {
1112 buf_strcpy(fname, mailbox_path(shared->mailbox));
1113 pretty_mailbox(fname);
1114 }
1115 }
1116
1117 if ((mw_enter_fname(prompt, fname, true, shared->mailbox, false, NULL, NULL,
1118 MUTT_SEL_NONE) == -1) ||
1119 buf_is_empty(fname))
1120 {
1121 buf_pool_release(&fname);
1122 return FR_NO_ACTION;
1123 }
1124
1125 if (OptNews)
1126 nntp_expand_path(fname->data, fname->dsize,
1127 &mod_data->current_news_srv->conn->account);
1128 else
1129 expand_path(fname, false);
1130
1131 if (imap_path_probe(buf_string(fname), NULL) != MUTT_IMAP)
1132 {
1133 if (pop_path_probe(buf_string(fname), NULL) != MUTT_POP)
1134 {
1135 if (!OptNews && (nntp_path_probe(buf_string(fname), NULL) != MUTT_NNTP))
1136 {
1137 if (mx_path_probe(buf_string(fname)) != MUTT_NOTMUCH)
1138 {
1139 /* check to make sure the file exists and is readable */
1140 if (access(buf_string(fname), R_OK) == -1)
1141 {
1142 mutt_perror("%s", buf_string(fname));
1143 buf_pool_release(&fname);
1144 return FR_ERROR;
1145 }
1146 }
1147 }
1148 }
1149 }
1150
1152
1153 struct Mailbox *m_attach = mx_path_resolve(buf_string(fname));
1154 const bool old_readonly = m_attach->readonly;
1155 if (!mx_mbox_open(m_attach, MUTT_READONLY))
1156 {
1157 mutt_error(_("Unable to open mailbox %s"), buf_string(fname));
1158 mx_fastclose_mailbox(m_attach, false);
1159 m_attach = NULL;
1160 buf_pool_release(&fname);
1161 return FR_ERROR;
1162 }
1163 buf_pool_release(&fname);
1164
1165 if (m_attach->msg_count == 0)
1166 {
1167 mx_mbox_close(m_attach);
1168 mutt_error(_("No messages in that folder"));
1169 return FR_ERROR;
1170 }
1171
1172 /* `$sort`, `$sort_aux`, `$use_threads` could be changed in dlg_index() */
1173 const enum EmailSortType old_sort = cs_subset_sort(shared->sub, "sort");
1174 const enum EmailSortType old_sort_aux = cs_subset_sort(shared->sub, "sort_aux");
1175 const unsigned char old_use_threads = cs_subset_enum(shared->sub, "use_threads");
1176
1177 mutt_message(_("Tag the messages you want to attach"));
1178 struct MuttWindow *dlg = index_pager_init();
1179 struct IndexSharedData *index_shared = dlg->wdata;
1180 index_shared->attach_msg = true;
1181 dialog_push(dlg);
1182 struct Mailbox *m_attach_new = dlg_index(dlg, m_attach);
1183 dialog_pop();
1184 mutt_window_free(&dlg);
1185
1186 if (!shared->mailbox)
1187 {
1188 /* Restore old $sort variables */
1189 cs_subset_str_native_set(shared->sub, "sort", old_sort, NULL);
1190 cs_subset_str_native_set(shared->sub, "sort_aux", old_sort_aux, NULL);
1191 cs_subset_str_native_set(shared->sub, "use_threads", old_use_threads, NULL);
1194 return FR_SUCCESS;
1195 }
1196
1197 bool added_attachment = false;
1198 for (int i = 0; i < m_attach_new->msg_count; i++)
1199 {
1200 if (!m_attach_new->emails[i])
1201 break;
1202 if (!message_is_tagged(m_attach_new->emails[i]))
1203 continue;
1204
1205 struct AttachPtr *ap = mutt_aptr_new();
1206 ap->body = mutt_make_message_attach(m_attach_new, m_attach_new->emails[i],
1207 true, shared->sub);
1208 if (ap->body)
1209 {
1210 added_attachment = true;
1211 update_idx(shared->adata->menu, shared->adata->actx, ap);
1212 }
1213 else
1214 {
1215 mutt_error(_("Unable to attach"));
1216 mutt_aptr_free(&ap);
1217 }
1218 }
1220
1221 if (m_attach_new == m_attach)
1222 {
1223 m_attach->readonly = old_readonly;
1224 }
1225 mx_fastclose_mailbox(m_attach_new, false);
1226
1227 /* Restore old $sort variables */
1228 cs_subset_str_native_set(shared->sub, "sort", old_sort, NULL);
1229 cs_subset_str_native_set(shared->sub, "sort_aux", old_sort_aux, NULL);
1230 cs_subset_str_native_set(shared->sub, "use_threads", old_use_threads, NULL);
1232 if (added_attachment)
1233 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1234 return added_attachment ? FR_SUCCESS : FR_ERROR;
1235}
@ MUTT_SEL_NONE
No flags are set.
Definition lib.h:59
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition helpers.c:71
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition helpers.c:266
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:216
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition mailbox.h:50
@ MUTT_POP
'POP3' Mailbox type
Definition mailbox.h:51
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition mailbox.h:48
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition dialog.c:109
void dialog_pop(void)
Hide a Window from the user.
Definition dialog.c:148
struct MuttWindow * index_pager_init(void)
Allocate the Windows for the Index/Pager.
Definition dlg_index.c:1462
EmailSortType
Methods for sorting Emails.
Definition sort.h:53
bool OptNews
(pseudo) used to change reader mode
Definition globals.c:53
struct Mailbox * dlg_index(struct MuttWindow *dlg, struct Mailbox *m_init)
Display a list of emails -.
Definition dlg_index.c:1121
#define mutt_perror(...)
Definition logging2.h:95
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox?
Definition nntp.c:2787
enum MailboxType pop_path_probe(const char *path, const struct stat *st)
Is this a POP Mailbox?
Definition pop.c:1170
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox?
Definition imap.c:2681
@ MENU_REDRAW_FULL
Redraw everything.
Definition lib.h:64
@ MODULE_ID_NNTP
ModuleNntp, Nntp
Definition module_api.h:81
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
void pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition muttlib.c:428
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
bool message_is_tagged(struct Email *e)
Is a message in the index tagged (and within limit)
Definition mview.c:361
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition mx.c:411
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition mx.c:285
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition mx.c:1323
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition mx.c:1647
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition mx.c:595
@ MUTT_READONLY
Open in read-only mode.
Definition mxapi.h:45
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition newsrc.c:557
struct NntpAccountData * nntp_select_server(struct Mailbox *m, const char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition newsrc.c:953
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg, struct ConfigSubset *sub)
Create a message attachment.
Definition sendlib.c:453
size_t dsize
Length of data.
Definition buffer.h:39
char * data
Pointer to data.
Definition buffer.h:37
struct Mailbox * mailbox
Current Mailbox.
Definition shared_data.h:37
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
Data shared between Index, Pager and Sidebar.
Definition shared_data.h:37
bool attach_msg
Are we in "attach message" mode?
Definition shared_data.h:46
A mailbox.
Definition mailbox.h:81
int msg_count
Total number of messages.
Definition mailbox.h:90
enum MailboxType type
Mailbox type.
Definition mailbox.h:104
struct Email ** emails
Array of Emails.
Definition mailbox.h:98
bool readonly
Don't allow changes to the mailbox.
Definition mailbox.h:118
void * wdata
Private data.
Container for Accounts, Notifications.
Definition neomutt.h:41
struct Connection * conn
Connection to NNTP Server.
Definition adata.h:63
Nntp private Module data.
Definition module_data.h:30
struct NntpAccountData * current_news_srv
Current NNTP news server.
Definition module_data.h:32
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition subset.c:303
+ Here is the call graph for this function:

◆ op_attach_detach()

static int op_attach_detach ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Delete the current entry - Implements compose_function_t -.

Definition at line 1240 of file functions.c.

1241{
1242 struct ComposeSharedData *shared = fdata->shared;
1243 struct AttachCtx *actx = shared->adata->actx;
1244 if (!check_count(actx))
1245 return FR_ERROR;
1246
1247 struct Menu *menu = shared->adata->menu;
1248 int rc = FR_NO_ACTION;
1249 struct AttachPtrArray aa = ARRAY_HEAD_INITIALIZER;
1250 aa_add_selection(&aa, actx, menu, menu->tag_prefix, event->count);
1251
1252 if (ARRAY_SIZE(&aa) > 1)
1253 {
1254 for (int i = ARRAY_SIZE(&aa) - 1; i >= 0; i--)
1255 {
1256 struct AttachPtr **app = ARRAY_GET(&aa, i);
1257 if (!app || !*app)
1258 continue;
1259 struct AttachPtr *ap = *app;
1260
1261 if (ap->unowned)
1262 ap->body->unlink = false;
1263
1264 const int index = body_index(actx, ap->body);
1265 if ((index >= 0) && (delete_attachment(actx, index, fdata->n->sub) == 0))
1266 rc = FR_SUCCESS;
1267 }
1268
1269 if (rc != FR_SUCCESS)
1270 {
1271 menu->num_tagged = 0;
1272 for (int i = 0; i < actx->idxlen; i++)
1273 {
1274 if (actx->idx[i]->body->tagged)
1275 menu->num_tagged++;
1276 }
1277 update_menu(actx, menu, false);
1278 ARRAY_FREE(&aa);
1279 return FR_ERROR;
1280 }
1281 }
1282 else
1283 {
1284 struct AttachPtr *cur_att = current_attachment(actx, menu);
1285 if (cur_att->unowned)
1286 cur_att->body->unlink = false;
1287
1288 const int index = menu_get_index(menu);
1289 if (delete_attachment(actx, index, fdata->n->sub) == -1)
1290 {
1291 menu->num_tagged = 0;
1292 for (int i = 0; i < actx->idxlen; i++)
1293 {
1294 if (actx->idx[i]->body->tagged)
1295 menu->num_tagged++;
1296 }
1297 update_menu(actx, menu, false);
1298 ARRAY_FREE(&aa);
1299 return FR_ERROR;
1300 }
1301
1302 rc = FR_SUCCESS;
1303 }
1304
1305 menu->num_tagged = 0;
1306 for (int i = 0; i < actx->idxlen; i++)
1307 {
1308 if (actx->idx[i]->body->tagged)
1309 menu->num_tagged++;
1310 }
1311
1312 update_menu(actx, menu, false);
1314
1315 const int index = menu_get_index(menu);
1316 if (index == 0)
1317 shared->email->body = actx->idx[0]->body;
1318
1319 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1320 ARRAY_FREE(&aa);
1321 return rc;
1322}
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
static bool check_count(struct AttachCtx *actx)
Check if there are any attachments.
Definition functions.c:231
static int body_index(struct AttachCtx *actx, const struct Body *b)
Find the index of an attachment body.
Definition functions.c:553
static int delete_attachment(struct AttachCtx *actx, int aidx, struct ConfigSubset *sub)
Delete an attachment.
Definition functions.c:373
void update_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition menu.c:155
struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition recvattach.c:71
int aa_add_selection(struct AttachPtrArray *aa, struct AttachCtx *actx, struct Menu *menu, bool use_tagged, int count)
Build a working set of Attachments for an action.
Definition selection.c:125
A set of attachments.
Definition attach.h:65
struct AttachPtr ** idx
Array of attachments.
Definition attach.h:69
short idxlen
Number of attachmentes.
Definition attach.h:70
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition body.h:68
bool tagged
This attachment is tagged.
Definition body.h:90
struct NeoMutt * n
NeoMutt application data.
Definition functions.h:34
struct Body * body
List of MIME parts.
Definition email.h:69
int count
Optional count prefix, e.g. 3 for 3j
Definition get.h:78
Definition lib.h:86
int num_tagged
Number of tagged entries.
Definition lib.h:101
bool tag_prefix
User has pressed <tag-prefix>
Definition lib.h:92
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:

◆ op_attach_edit_content_id()

static int op_attach_edit_content_id ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit the 'Content-ID' of the attachment - Implements compose_function_t -.

Definition at line 1327 of file functions.c.

1329{
1330 struct ComposeSharedData *shared = fdata->shared;
1331 struct AttachCtx *actx = shared->adata->actx;
1332 if (!check_count(actx))
1333 return FR_ERROR;
1334
1335 int rc = FR_NO_ACTION;
1336 struct Menu *menu = shared->adata->menu;
1337 struct Buffer *buf = buf_pool_get();
1338 struct Buffer *cid = buf_pool_get();
1339 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1340 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
1341
1342 struct AttachPtr *cur_att = current_attachment(actx, menu);
1343
1344 char *id = cur_att->body->content_id;
1345 if (id)
1346 {
1347 buf_strcpy(buf, id);
1348 }
1349 else
1350 {
1351 id = gen_cid();
1352 buf_strcpy(buf, id);
1353 FREE(&id);
1354 }
1355
1356 if (mw_get_field("Content-ID: ", buf, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) == 0)
1357 {
1358 if (check_cid(buf_string(buf)))
1359 {
1360 bool changed = false;
1361 struct Body **bp = NULL;
1362 ARRAY_FOREACH(bp, &ba)
1363 {
1364 const bool multi = (ARRAY_SIZE(&ba) > 1);
1365 int suffix = multi ? (ARRAY_FOREACH_IDX_bp + 1) : 0;
1366
1367 do
1368 {
1369 if (suffix == 0)
1370 buf_strcpy(cid, buf_string(buf));
1371 else
1372 buf_printf(cid, "%s-%d", buf_string(buf), suffix);
1373
1374 suffix++;
1375 } while (content_id_exists(actx, *bp, buf_string(cid)));
1376
1377 if (!mutt_str_equal((*bp)->content_id, buf_string(cid)))
1378 {
1379 mutt_str_replace(&(*bp)->content_id, buf_string(cid));
1380 changed = true;
1381 }
1382 }
1383
1384 if (changed)
1385 {
1388 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1389 rc = FR_SUCCESS;
1390 }
1391 }
1392 else
1393 {
1394 mutt_error(_("Content-ID can only contain the characters: -.0-9@A-Z_a-z"));
1395 rc = FR_ERROR;
1396 }
1397 }
1398
1399 ARRAY_FREE(&ba);
1400 buf_pool_release(&cid);
1401 buf_pool_release(&buf);
1402
1403 if (rc != FR_ERROR)
1405
1406 return rc;
1407}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
static char * gen_cid(void)
Generate a random Content ID.
Definition functions.c:248
static MenuRedrawFlags selection_redraw_flags(size_t count)
Choose redraw flags for a selection.
Definition functions.c:671
static bool check_cid(const char *cid)
Check if a Content-ID is valid.
Definition functions.c:264
static bool content_id_exists(struct AttachCtx *actx, const struct Body *skip, const char *cid)
Check whether a Content-ID is already in use.
Definition functions.c:284
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:502
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:61
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:284
int ba_add_selection(struct BodyArray *ba, struct AttachCtx *actx, struct Menu *menu, bool use_tagged, int count)
Build a working set of attachment bodies for an action.
Definition selection.c:164
The body of an email.
Definition body.h:36
char * content_id
Content-Id (RFC2392)
Definition body.h:58
+ Here is the call graph for this function:

◆ op_attach_edit_description()

static int op_attach_edit_description ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit attachment description - Implements compose_function_t -.

Definition at line 1412 of file functions.c.

1414{
1415 struct ComposeSharedData *shared = fdata->shared;
1416 struct AttachCtx *actx = shared->adata->actx;
1417 if (!check_count(actx))
1418 return FR_ERROR;
1419
1420 int rc = FR_NO_ACTION;
1421 struct Menu *menu = shared->adata->menu;
1422 struct Buffer *buf = buf_pool_get();
1423 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1424
1425 struct AttachPtr *cur_att = current_attachment(actx, menu);
1426 buf_strcpy(buf, cur_att->body->description);
1427
1428 /* header names should not be translated */
1429 if (mw_get_field("Description: ", buf, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) == 0)
1430 {
1431 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
1432
1433 bool changed = false;
1434 struct Body **bp = NULL;
1435 ARRAY_FOREACH(bp, &ba)
1436 {
1437 if (!mutt_str_equal((*bp)->description, buf_string(buf)))
1438 {
1439 mutt_str_replace(&(*bp)->description, buf_string(buf));
1440 changed = true;
1441 }
1442 }
1443
1444 if (changed)
1445 {
1447 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1448 rc = FR_SUCCESS;
1449 }
1450 }
1451
1452 ARRAY_FREE(&ba);
1453 buf_pool_release(&buf);
1454 return rc;
1455}
char * description
content-description
Definition body.h:55
+ Here is the call graph for this function:

◆ op_attach_edit_encoding()

static int op_attach_edit_encoding ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit attachment transfer-encoding - Implements compose_function_t -.

Definition at line 1460 of file functions.c.

1462{
1463 struct ComposeSharedData *shared = fdata->shared;
1464 struct AttachCtx *actx = shared->adata->actx;
1465 if (!check_count(actx))
1466 return FR_ERROR;
1467
1468 int rc = FR_NO_ACTION;
1469 struct Menu *menu = shared->adata->menu;
1470 struct Buffer *buf = buf_pool_get();
1471 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1472
1473 struct AttachPtr *cur_att = current_attachment(actx, menu);
1474 buf_strcpy(buf, ENCODING(cur_att->body->encoding));
1475
1476 if ((mw_get_field("Content-Transfer-Encoding: ", buf, MUTT_COMP_NONE,
1477 HC_OTHER, NULL, NULL) == 0) &&
1478 !buf_is_empty(buf))
1479 {
1480 int enc = mutt_check_encoding(buf_string(buf));
1481 if ((enc != ENC_OTHER) && (enc != ENC_UUENCODED))
1482 {
1483 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
1484
1485 bool changed = false;
1486 struct Body **bp = NULL;
1487 ARRAY_FOREACH(bp, &ba)
1488 {
1489 if ((*bp)->encoding != enc)
1490 {
1491 (*bp)->encoding = enc;
1492 changed = true;
1493 }
1494 }
1495
1496 if (changed)
1497 {
1501 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1502 rc = FR_SUCCESS;
1503 }
1504 }
1505 else
1506 {
1507 mutt_error(_("Invalid encoding"));
1508 rc = FR_ERROR;
1509 }
1510 }
1511
1512 ARRAY_FREE(&ba);
1513 buf_pool_release(&buf);
1514 return rc;
1515}
int mutt_check_encoding(const char *c)
Check the encoding type.
Definition parse.c:404
@ ENC_UUENCODED
UUEncoded text.
Definition mime.h:54
@ ENC_OTHER
Encoding unknown.
Definition mime.h:48
#define ENCODING(x)
Get the encoding name for an encoding type.
Definition mime.h:97
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
+ Here is the call graph for this function:

◆ op_attach_edit_language()

static int op_attach_edit_language ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit the 'Content-Language' of the attachment - Implements compose_function_t -.

Definition at line 1520 of file functions.c.

1522{
1523 struct ComposeSharedData *shared = fdata->shared;
1524 struct AttachCtx *actx = shared->adata->actx;
1525 if (!check_count(actx))
1526 return FR_ERROR;
1527
1528 int rc = FR_NO_ACTION;
1529 struct Menu *menu = shared->adata->menu;
1530 struct Buffer *buf = buf_pool_get();
1531 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1532 struct AttachPtr *cur_att = current_attachment(actx, menu);
1533
1534 buf_strcpy(buf, cur_att->body->language);
1535 if (mw_get_field("Content-Language: ", buf, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) == 0)
1536 {
1537 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
1538
1539 bool changed = false;
1540 struct Body **bp = NULL;
1541 ARRAY_FOREACH(bp, &ba)
1542 {
1543 if (!mutt_str_equal((*bp)->language, buf_string(buf)))
1544 {
1545 mutt_str_replace(&(*bp)->language, buf_string(buf));
1546 changed = true;
1547 }
1548 }
1549
1550 if (changed)
1551 {
1554 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1555 rc = FR_SUCCESS;
1556 }
1558 }
1559 else
1560 {
1561 mutt_warning(_("Empty 'Content-Language'"));
1562 rc = FR_ERROR;
1563 }
1564
1565 ARRAY_FREE(&ba);
1566 buf_pool_release(&buf);
1567 return rc;
1568}
#define mutt_warning(...)
Definition logging2.h:92
char * language
content-language (RFC8255)
Definition body.h:78
+ Here is the call graph for this function:

◆ op_attach_edit_mime()

static int op_attach_edit_mime ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit attachment using mailcap entry - Implements compose_function_t -.

Definition at line 1573 of file functions.c.

1574{
1575 struct ComposeSharedData *shared = fdata->shared;
1576 struct AttachCtx *actx = shared->adata->actx;
1577 if (!check_count(actx))
1578 return FR_ERROR;
1579
1580 int rc = FR_NO_ACTION;
1581 struct Menu *menu = shared->adata->menu;
1582 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1583 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
1584 if (ARRAY_EMPTY(&ba))
1585 goto done;
1586
1587 struct Body **bp = NULL;
1588 ARRAY_FOREACH(bp, &ba)
1589 {
1590 if (!mutt_edit_attachment(*bp))
1591 continue;
1592
1593 mutt_update_encoding(*bp, shared->sub);
1594 rc = FR_SUCCESS;
1595 }
1596
1597 if (rc != FR_SUCCESS)
1598 goto done;
1599
1601 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1602
1603done:
1604 ARRAY_FREE(&ba);
1605 return rc;
1606}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
bool mutt_edit_attachment(struct Body *b)
Edit an attachment.
void mutt_update_encoding(struct Body *b, struct ConfigSubset *sub)
Update the encoding type.
Definition sendlib.c:421
+ Here is the call graph for this function:

◆ op_attach_edit_type()

static int op_attach_edit_type ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit attachment content type - Implements compose_function_t -.

Definition at line 1611 of file functions.c.

1612{
1613 struct ComposeSharedData *shared = fdata->shared;
1614 if (!check_count(shared->adata->actx))
1615 return FR_ERROR;
1616
1617 struct AttachPtr *cur_att = current_attachment(shared->adata->actx,
1618 shared->adata->menu);
1619 if (!mutt_edit_content_type(NULL, cur_att->body, NULL))
1620 return FR_NO_ACTION;
1621
1622 /* this may have been a change to text/something */
1623 mutt_update_encoding(cur_att->body, shared->sub);
1625 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1626 return FR_SUCCESS;
1627}
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition external.c:1073
@ MENU_REDRAW_CURRENT
Redraw the current line of the menu.
Definition lib.h:63
+ Here is the call graph for this function:

◆ op_attach_filter()

static int op_attach_filter ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Filter attachment through a shell command - Implements compose_function_t -.

This function handles:

  • OP_ATTACH_FILTER
  • OP_PIPE

Definition at line 1636 of file functions.c.

1637{
1638 struct ComposeSharedData *shared = fdata->shared;
1639 struct AttachCtx *actx = shared->adata->actx;
1640 if (!check_count(actx))
1641 return FR_ERROR;
1642
1643 struct Menu *menu = shared->adata->menu;
1644 struct AttachPtrArray aa = ARRAY_HEAD_INITIALIZER;
1645 aa_add_selection(&aa, actx, menu, menu->tag_prefix, event->count);
1646 struct AttachPtr **app = NULL;
1647 ARRAY_FOREACH(app, &aa)
1648 {
1649 if ((*app)->body->type == TYPE_MULTIPART)
1650 {
1651 ARRAY_FREE(&aa);
1652 mutt_error(_("Can't filter multipart attachments"));
1653 return FR_ERROR;
1654 }
1655 }
1656
1657 const int op = event->op;
1658 mutt_pipe_attachment_list(&aa, (op == OP_ATTACH_FILTER));
1659 if (op == OP_ATTACH_FILTER) /* cte might have changed */
1660 {
1662 }
1663 ARRAY_FREE(&aa);
1665 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1666 return FR_SUCCESS;
1667}
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
void mutt_pipe_attachment_list(struct AttachPtrArray *aa, bool filter)
Pipe selected attachments to a command.
Definition recvattach.c:697
+ Here is the call graph for this function:

◆ op_attach_get_attachment()

static int op_attach_get_attachment ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Get a temporary copy of an attachment - Implements compose_function_t -.

Definition at line 1672 of file functions.c.

1674{
1675 struct ComposeSharedData *shared = fdata->shared;
1676 struct AttachCtx *actx = shared->adata->actx;
1677 if (!check_count(actx))
1678 return FR_ERROR;
1679
1680 int rc = FR_ERROR;
1681 struct Menu *menu = shared->adata->menu;
1682 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1683 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
1684 if (ARRAY_EMPTY(&ba))
1685 goto done;
1686
1687 struct Body **bp = NULL;
1688 bool got_attachment = false;
1689 ARRAY_FOREACH(bp, &ba)
1690 {
1691 if ((*bp)->type == TYPE_MULTIPART)
1692 {
1693 mutt_warning(_("Can't get multipart attachments"));
1694 continue;
1695 }
1697 got_attachment = true;
1698 }
1699
1700 if (got_attachment)
1701 {
1703 rc = FR_SUCCESS;
1704 }
1705
1706done:
1707 ARRAY_FREE(&ba);
1708 /* No send2hook since this doesn't change the message. */
1709 return rc;
1710}
int mutt_get_tmp_attachment(struct Body *b)
Get a temporary copy of an attachment.
Definition mutt_attach.c:68
+ Here is the call graph for this function:

◆ op_attach_group_alts()

static int op_attach_group_alts ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Group selected attachments as 'multipart/alternative' - Implements compose_function_t -.

Definition at line 1715 of file functions.c.

1716{
1717 struct ComposeSharedData *shared = fdata->shared;
1718 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1719 ba_add_selection(&ba, shared->adata->actx, shared->adata->menu,
1720 shared->adata->menu->tag_prefix, event->count);
1721 if (ARRAY_SIZE(&ba) < 2)
1722 {
1723 ARRAY_FREE(&ba);
1724 mutt_error(_("Grouping 'alternatives' requires at least 2 selected attachments"));
1725 return FR_ERROR;
1726 }
1727
1728 const int rc = group_attachments(shared, "alternative", &ba);
1729 ARRAY_FREE(&ba);
1730 return rc;
1731}
static int group_attachments(struct ComposeSharedData *shared, char *subtype, struct BodyArray *ba)
Group selected attachments into a multipart group.
Definition functions.c:771
+ Here is the call graph for this function:

◆ op_attach_group_lingual()

static int op_attach_group_lingual ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Group selected attachments as 'multipart/multilingual' - Implements compose_function_t -.

Definition at line 1736 of file functions.c.

1738{
1739 struct ComposeSharedData *shared = fdata->shared;
1740 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1741 ba_add_selection(&ba, shared->adata->actx, shared->adata->menu,
1742 shared->adata->menu->tag_prefix, event->count);
1743 if (ARRAY_SIZE(&ba) < 2)
1744 {
1745 ARRAY_FREE(&ba);
1746 mutt_error(_("Grouping 'multilingual' requires at least 2 selected attachments"));
1747 return FR_ERROR;
1748 }
1749
1750 int tagged_with_lang_num = 0;
1751 struct Body **bp = NULL;
1752 ARRAY_FOREACH(bp, &ba)
1753 {
1754 if ((*bp)->language && *(*bp)->language)
1755 tagged_with_lang_num++;
1756 }
1757
1758 if (ARRAY_SIZE(&ba) != tagged_with_lang_num)
1759 {
1760 if (query_yesorno(_("Not all parts have 'Content-Language' set, continue?"),
1761 MUTT_YES) != MUTT_YES)
1762 {
1763 ARRAY_FREE(&ba);
1764 mutt_message(_("Not sending this message"));
1765 return FR_ERROR;
1766 }
1767 }
1768
1769 const int rc = group_attachments(shared, "multilingual", &ba);
1770 ARRAY_FREE(&ba);
1771 return rc;
1772}
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
enum QuadOption query_yesorno(const char *prompt, enum QuadOption def)
Ask the user a Yes/No question.
Definition question.c:329
+ Here is the call graph for this function:

◆ op_attach_group_related()

static int op_attach_group_related ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Group selected attachments as 'multipart/related' - Implements compose_function_t -.

Definition at line 1777 of file functions.c.

1779{
1780 struct ComposeSharedData *shared = fdata->shared;
1781 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
1782 ba_add_selection(&ba, shared->adata->actx, shared->adata->menu,
1783 shared->adata->menu->tag_prefix, event->count);
1784 if (ARRAY_SIZE(&ba) < 2)
1785 {
1786 ARRAY_FREE(&ba);
1787 mutt_error(_("Grouping 'related' requires at least 2 selected attachments"));
1788 return FR_ERROR;
1789 }
1790
1791 // ensure Content-ID is set for selected attachments
1792 struct Body **bp = NULL;
1793 ARRAY_FOREACH(bp, &ba)
1794 {
1795 if ((*bp)->type == TYPE_MULTIPART)
1796 continue;
1797
1798 if (!(*bp)->content_id)
1799 {
1800 (*bp)->content_id = gen_cid();
1801 }
1802 }
1803
1804 const int rc = group_attachments(shared, "related", &ba);
1805 ARRAY_FREE(&ba);
1806 return rc;
1807}
+ Here is the call graph for this function:

◆ op_attach_move_down()

static int op_attach_move_down ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Move an attachment down in the attachment list - Implements compose_function_t -.

Definition at line 1812 of file functions.c.

1813{
1814 struct ComposeSharedData *shared = fdata->shared;
1815 if (shared->adata->menu->tag_prefix || (event->count > 1))
1816 return move_attachment(shared, false, event->count);
1817
1818 int index = menu_get_index(shared->adata->menu);
1819
1820 struct AttachCtx *actx = shared->adata->actx;
1821
1822 if (index < 0)
1823 return FR_ERROR;
1824
1825 if (index == (actx->idxlen - 1))
1826 {
1827 mutt_error(_("Attachment is already at bottom"));
1828 return FR_ERROR;
1829 }
1830 if ((actx->idx[index]->parent_type == TYPE_MULTIPART) &&
1831 !actx->idx[index]->body->next)
1832 {
1833 mutt_error(_("Attachment can't be moved out of group"));
1834 return FR_ERROR;
1835 }
1836
1837 // find next attachment at current level
1838 int nextidx = index + 1;
1839 while ((nextidx < actx->idxlen) &&
1840 (actx->idx[nextidx]->level > actx->idx[index]->level))
1841 {
1842 nextidx++;
1843 }
1844 if (nextidx == actx->idxlen)
1845 {
1846 mutt_error(_("Attachment is already at bottom"));
1847 return FR_ERROR;
1848 }
1849
1850 // find final position
1851 int finalidx = index + 1;
1852 if (nextidx < actx->idxlen - 1)
1853 {
1854 if ((actx->idx[nextidx]->body->type == TYPE_MULTIPART) &&
1855 (actx->idx[nextidx + 1]->level > actx->idx[nextidx]->level))
1856 {
1857 finalidx += attach_body_count(actx->idx[nextidx]->body->parts, true);
1858 }
1859 }
1860
1861 compose_attach_swap(shared->email, shared->adata->actx, index, nextidx);
1862 mutt_update_tree(shared->adata->actx);
1865 menu_set_index(shared->adata->menu, finalidx);
1866 return FR_SUCCESS;
1867}
int attach_body_count(struct Body *body, bool recurse)
Count bodies.
Definition lib.c:42
static void compose_attach_swap(struct Email *e, struct AttachCtx *actx, int first, int second)
Swap two adjacent entries in the attachment list.
Definition functions.c:487
static int move_attachment(struct ComposeSharedData *shared, bool up, int count)
Move attachments in the attachment list.
Definition functions.c:683
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition menu.c:169
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition recvattach.c:116
int level
Nesting depth of attachment.
Definition attach.h:41
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition attach.h:39
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
struct Body * next
next attachment in the list
Definition body.h:72
unsigned int type
content-type primary type, ContentType
Definition body.h:40
+ Here is the call graph for this function:

◆ op_attach_move_up()

static int op_attach_move_up ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Move an attachment up in the attachment list - Implements compose_function_t -.

Definition at line 1872 of file functions.c.

1873{
1874 struct ComposeSharedData *shared = fdata->shared;
1875 if (shared->adata->menu->tag_prefix || (event->count > 1))
1876 return move_attachment(shared, true, event->count);
1877
1878 int index = menu_get_index(shared->adata->menu);
1879 if (index < 0)
1880 return FR_ERROR;
1881
1882 struct AttachCtx *actx = shared->adata->actx;
1883
1884 if (index == 0)
1885 {
1886 mutt_error(_("Attachment is already at top"));
1887 return FR_ERROR;
1888 }
1889 if (actx->idx[index - 1]->level < actx->idx[index]->level)
1890 {
1891 mutt_error(_("Attachment can't be moved out of group"));
1892 return FR_ERROR;
1893 }
1894
1895 // find previous attachment at current level
1896 int previdx = index - 1;
1897 while ((previdx > 0) && (actx->idx[previdx]->level > actx->idx[index]->level))
1898 previdx--;
1899
1900 compose_attach_swap(shared->email, actx, previdx, index);
1901 mutt_update_tree(actx);
1904 menu_set_index(shared->adata->menu, previdx);
1905 return FR_SUCCESS;
1906}
+ Here is the call graph for this function:

◆ op_attach_new_mime()

static int op_attach_new_mime ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Compose new attachment using mailcap entry - Implements compose_function_t -.

Definition at line 1911 of file functions.c.

1912{
1913 struct ComposeSharedData *shared = fdata->shared;
1914 int rc = FR_NO_ACTION;
1915 struct Buffer *fname = buf_pool_get();
1916 struct Buffer *type = NULL;
1917 struct AttachPtr *ap = NULL;
1918
1919 struct FileCompletionData cdata = { false, shared->mailbox, NULL, NULL, NULL };
1920 if ((mw_get_field(_("New file: "), fname, MUTT_COMP_NONE, HC_FILE,
1921 &CompleteFileOps, &cdata) != 0) ||
1922 buf_is_empty(fname))
1923 {
1924 goto done;
1925 }
1926 expand_path(fname, false);
1927
1928 /* Call to lookup_mime_type () ? maybe later */
1929 type = buf_pool_get();
1930 if ((mw_get_field("Content-Type: ", type, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) != 0) ||
1931 buf_is_empty(type))
1932 {
1933 goto done;
1934 }
1935
1936 rc = FR_ERROR;
1937 char *p = strchr(buf_string(type), '/');
1938 if (!p)
1939 {
1940 mutt_error(_("Content-Type is of the form base/sub"));
1941 goto done;
1942 }
1943 *p++ = 0;
1944 enum ContentType itype = mutt_check_mime_type(buf_string(type));
1945 if (itype == TYPE_OTHER)
1946 {
1947 mutt_error(_("Unknown Content-Type %s"), buf_string(type));
1948 goto done;
1949 }
1950
1951 ap = mutt_aptr_new();
1952 /* Touch the file */
1953 if (!mutt_file_touch(buf_string(fname)))
1954 {
1955 mutt_error(_("Can't create file %s"), buf_string(fname));
1956 goto done;
1957 }
1958
1959 ap->body = mutt_make_file_attach(buf_string(fname), shared->sub);
1960 if (!ap->body)
1961 {
1962 mutt_error(_("Error attaching file"));
1963 goto done;
1964 }
1965 update_idx(shared->adata->menu, shared->adata->actx, ap);
1966 ap = NULL; // shared->adata->actx has taken ownership
1967
1968 struct AttachPtr *cur_att = current_attachment(shared->adata->actx,
1969 shared->adata->menu);
1970 cur_att->body->type = itype;
1971 mutt_str_replace(&cur_att->body->subtype, p);
1972 cur_att->body->unlink = true;
1975
1976 if (mutt_compose_attachment(cur_att->body))
1977 {
1978 mutt_update_encoding(cur_att->body, shared->sub);
1980 }
1981 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1982 rc = FR_SUCCESS;
1983
1984done:
1985 mutt_aptr_free(&ap);
1986 buf_pool_release(&type);
1987 buf_pool_release(&fname);
1988 return rc;
1989}
const struct CompleteOps CompleteFileOps
Auto-Completion of Files.
Definition complete.c:152
enum ContentType mutt_check_mime_type(const char *s)
Check a MIME type string.
Definition parse.c:333
bool mutt_file_touch(const char *path)
Make sure a file exists.
Definition file.c:974
@ HC_FILE
Files.
Definition lib.h:59
ContentType
Content-Type.
Definition mime.h:30
@ TYPE_OTHER
Unknown Content-Type.
Definition mime.h:31
int mutt_compose_attachment(struct Body *b)
Create an attachment.
char * subtype
content-type subtype
Definition body.h:61
int rc
Return code to leave compose.
Definition shared_data.h:47
Input for the file completion function.
Definition curs_lib.h:39
+ Here is the call graph for this function:

◆ op_attach_print()

static int op_attach_print ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Print the current entry - Implements compose_function_t -.

Definition at line 1994 of file functions.c.

1995{
1996 struct ComposeSharedData *shared = fdata->shared;
1997 struct AttachCtx *actx = shared->adata->actx;
1998 if (!check_count(actx))
1999 return FR_ERROR;
2000
2001 struct Menu *menu = shared->adata->menu;
2002 struct AttachPtrArray aa = ARRAY_HEAD_INITIALIZER;
2003 aa_add_selection(&aa, actx, menu, menu->tag_prefix, event->count);
2004 struct AttachPtr **app = NULL;
2005 ARRAY_FOREACH(app, &aa)
2006 {
2007 if ((*app)->body->type == TYPE_MULTIPART)
2008 {
2009 ARRAY_FREE(&aa);
2010 mutt_error(_("Can't print multipart attachments"));
2011 return FR_ERROR;
2012 }
2013 }
2014
2016 ARRAY_FREE(&aa);
2017 /* no send2hook, since this doesn't modify the message */
2018 return FR_SUCCESS;
2019}
void mutt_print_attachment_list(struct AttachPtrArray *aa)
Print selected attachments.
Definition recvattach.c:846
+ Here is the call graph for this function:

◆ op_attach_rename_attachment()

static int op_attach_rename_attachment ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Send attachment with a different name - Implements compose_function_t -.

Definition at line 2024 of file functions.c.

2026{
2027 struct ComposeSharedData *shared = fdata->shared;
2028 if (!check_count(shared->adata->actx))
2029 return FR_ERROR;
2030 char *src = NULL;
2031 struct AttachPtr *cur_att = current_attachment(shared->adata->actx,
2032 shared->adata->menu);
2033 if (cur_att->body->d_filename)
2034 src = cur_att->body->d_filename;
2035 else
2036 src = cur_att->body->filename;
2037 struct Buffer *fname = buf_pool_get();
2038 buf_strcpy(fname, mutt_path_basename(NONULL(src)));
2039 struct FileCompletionData cdata = { false, shared->mailbox, NULL, NULL, NULL };
2040 int rc = mw_get_field(_("Send attachment with name: "), fname, MUTT_COMP_NONE,
2041 HC_FILE, &CompleteFileOps, &cdata);
2042 if (rc == 0)
2043 {
2044 // It's valid to set an empty string here, to erase what was set
2045 mutt_str_replace(&cur_att->body->d_filename, buf_string(fname));
2047 }
2048 buf_pool_release(&fname);
2049 return FR_SUCCESS;
2050}
const char * mutt_path_basename(const char *path)
Find the last component for a pathname.
Definition path.c:282
#define NONULL(x)
Definition string2.h:44
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition body.h:56
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
+ Here is the call graph for this function:

◆ op_attach_save()

static int op_attach_save ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Save message/attachment to a mailbox/file - Implements compose_function_t -.

Definition at line 2055 of file functions.c.

2056{
2057 struct ComposeSharedData *shared = fdata->shared;
2058 struct AttachCtx *actx = shared->adata->actx;
2059 if (!check_count(actx))
2060 return FR_ERROR;
2061
2062 struct Menu *menu = shared->adata->menu;
2063 struct AttachPtrArray aa = ARRAY_HEAD_INITIALIZER;
2064 aa_add_selection(&aa, actx, menu, menu->tag_prefix, event->count);
2065 struct AttachPtr **app = NULL;
2066 ARRAY_FOREACH(app, &aa)
2067 {
2068 if ((*app)->body->type == TYPE_MULTIPART)
2069 {
2070 ARRAY_FREE(&aa);
2071 mutt_error(_("Can't save multipart attachments"));
2072 return FR_ERROR;
2073 }
2074 }
2075
2076 mutt_save_attachment_list(&aa, NULL, menu);
2077 ARRAY_FREE(&aa);
2078 /* no send2hook, since this doesn't modify the message */
2079 return FR_SUCCESS;
2080}
void mutt_save_attachment_list(struct AttachPtrArray *aa, struct Email *e, struct Menu *menu)
Save a list of selected attachments.
Definition recvattach.c:423
+ Here is the call graph for this function:

◆ op_attach_toggle_disposition()

static int op_attach_toggle_disposition ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Toggle disposition between inline/attachment - Implements compose_function_t -.

Definition at line 2085 of file functions.c.

2087{
2088 struct ComposeSharedData *shared = fdata->shared;
2089 /* toggle the content-disposition between inline/attachment */
2090 struct AttachCtx *actx = shared->adata->actx;
2091 if (!check_count(actx))
2092 return FR_ERROR;
2093
2094 int rc = FR_NO_ACTION;
2095 struct Menu *menu = shared->adata->menu;
2096 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
2097 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
2098
2099 struct Body **bp = NULL;
2100 ARRAY_FOREACH(bp, &ba)
2101 {
2102 (*bp)->disposition = ((*bp)->disposition == DISP_INLINE) ? DISP_ATTACH : DISP_INLINE;
2103 rc = FR_SUCCESS;
2104 }
2105
2106 if (rc == FR_SUCCESS)
2108
2109 ARRAY_FREE(&ba);
2111 return rc;
2112}
@ DISP_ATTACH
Content is attached.
Definition mime.h:63
@ DISP_INLINE
Content is inline.
Definition mime.h:62
unsigned int disposition
content-disposition, ContentDisposition
Definition body.h:42
+ Here is the call graph for this function:

◆ op_attach_toggle_recode()

static int op_attach_toggle_recode ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Toggle recoding of this attachment - Implements compose_function_t -.

Definition at line 2117 of file functions.c.

2119{
2120 struct ComposeSharedData *shared = fdata->shared;
2121 struct AttachCtx *actx = shared->adata->actx;
2122 if (!check_count(actx))
2123 return FR_ERROR;
2124
2125 int rc = FR_NO_ACTION;
2126 struct Menu *menu = shared->adata->menu;
2127 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
2128 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
2129
2130 struct Body **bp = NULL;
2131 ARRAY_FOREACH(bp, &ba)
2132 {
2133 if (!mutt_is_text_part(*bp))
2134 continue;
2135
2136 (*bp)->noconv = !(*bp)->noconv;
2137 rc = FR_SUCCESS;
2138 }
2139
2140 if (rc == FR_NO_ACTION)
2141 {
2142 mutt_error(_("Recoding only affects text attachments"));
2143 ARRAY_FREE(&ba);
2144 return FR_ERROR;
2145 }
2146
2147 if (ARRAY_SIZE(&ba) == 1)
2148 {
2149 struct AttachPtr *cur_att = current_attachment(actx, menu);
2150 if (cur_att->body->noconv)
2151 mutt_message(_("The current attachment won't be converted"));
2152 else
2153 mutt_message(_("The current attachment will be converted"));
2154 }
2155 else
2156 {
2158 }
2159
2161 ARRAY_FREE(&ba);
2162 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2163 return FR_SUCCESS;
2164}
bool mutt_is_text_part(const struct Body *b)
Is this part of an email in plain text?
Definition muttlib.c:396
bool noconv
Don't do character set conversion.
Definition body.h:46
+ Here is the call graph for this function:

◆ op_attach_toggle_unlink()

static int op_attach_toggle_unlink ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Toggle whether to delete file after sending it - Implements compose_function_t -.

Definition at line 2169 of file functions.c.

2171{
2172 struct ComposeSharedData *shared = fdata->shared;
2173 struct AttachCtx *actx = shared->adata->actx;
2174 if (!check_count(actx))
2175 return FR_ERROR;
2176
2177 int rc = FR_NO_ACTION;
2178 struct Menu *menu = shared->adata->menu;
2179 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
2180 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
2181
2182 struct Body **bp = NULL;
2183 ARRAY_FOREACH(bp, &ba)
2184 {
2185 (*bp)->unlink = !(*bp)->unlink;
2186 rc = FR_SUCCESS;
2187 }
2188
2189 if (rc == FR_SUCCESS)
2191
2192 ARRAY_FREE(&ba);
2193 /* No send2hook since this doesn't change the message. */
2194 return rc;
2195}
+ Here is the call graph for this function:

◆ op_attach_ungroup()

static int op_attach_ungroup ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Ungroup a 'multipart' attachment - Implements compose_function_t -.

Definition at line 2200 of file functions.c.

2201{
2202 struct ComposeSharedData *shared = fdata->shared;
2203 if (shared->adata->actx->idx[shared->adata->menu->current]->body->type != TYPE_MULTIPART)
2204 {
2205 mutt_error(_("Attachment is not 'multipart'"));
2206 return FR_ERROR;
2207 }
2208
2209 int aidx = shared->adata->menu->current;
2210 struct AttachCtx *actx = shared->adata->actx;
2211 struct Body *b = actx->idx[aidx]->body;
2212 struct Body *b_next = b->next;
2213 struct Body *b_previous = NULL;
2214 struct Body *b_parent = NULL;
2215 int parent_type = actx->idx[aidx]->parent_type;
2216 int level = actx->idx[aidx]->level;
2217
2218 // reorder body pointers
2219 if (attach_body_previous(shared->email->body, b, &b_previous))
2220 b_previous->next = b->parts;
2221 else if (attach_body_parent(shared->email->body, NULL, b, &b_parent))
2222 b_parent->parts = b->parts;
2223 else
2224 shared->email->body = b->parts;
2225
2226 // update attachment list
2227 int i = aidx + 1;
2228 while ((i < actx->idxlen) && (actx->idx[i]->level > level))
2229 {
2230 actx->idx[i]->level--;
2231 if (actx->idx[i]->level == level)
2232 {
2233 actx->idx[i]->parent_type = parent_type;
2234 // set body->next for final attachment in group
2235 if (!actx->idx[i]->body->next)
2236 actx->idx[i]->body->next = b_next;
2237 }
2238 i++;
2239 }
2240
2241 // free memory
2242 actx->idx[aidx]->body->parts = NULL;
2243 actx->idx[aidx]->body->next = NULL;
2244 actx->idx[aidx]->body->email = NULL;
2245 mutt_body_free(&actx->idx[aidx]->body);
2246 FREE(&actx->idx[aidx]->tree);
2247 FREE(&actx->idx[aidx]);
2248
2249 // reorder attachment list
2250 for (int j = aidx; j < (actx->idxlen - 1); j++)
2251 actx->idx[j] = actx->idx[j + 1];
2252 actx->idx[actx->idxlen - 1] = NULL;
2253 actx->idxlen--;
2254 update_menu(actx, shared->adata->menu, false);
2255
2256 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2257 return FR_SUCCESS;
2258}
bool attach_body_parent(struct Body *start, struct Body *start_parent, struct Body *body, struct Body **body_parent)
Find the parent of a body.
Definition lib.c:71
bool attach_body_previous(struct Body *start, struct Body *body, struct Body **previous)
Find the previous body of a body.
Definition lib.c:142
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
char * tree
Tree characters to display.
Definition attach.h:40
struct Email * email
header information for message/rfc822
Definition body.h:74
int current
Current entry.
Definition lib.h:87
+ Here is the call graph for this function:

◆ op_attach_update_encoding()

static int op_attach_update_encoding ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Update an attachment's encoding info - Implements compose_function_t -.

Definition at line 2263 of file functions.c.

2265{
2266 struct ComposeSharedData *shared = fdata->shared;
2267 struct AttachCtx *actx = shared->adata->actx;
2268 if (!check_count(actx))
2269 return FR_ERROR;
2270
2271 int rc = FR_NO_ACTION;
2272 struct Menu *menu = shared->adata->menu;
2273 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
2274 ba_add_selection(&ba, actx, menu, menu->tag_prefix, event->count);
2275 if (ARRAY_EMPTY(&ba))
2276 goto done;
2277
2278 struct Body **bp = NULL;
2279 ARRAY_FOREACH(bp, &ba)
2280 {
2281 mutt_update_encoding(*bp, shared->sub);
2282 }
2283
2286 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2287 rc = FR_SUCCESS;
2288
2289done:
2290 ARRAY_FREE(&ba);
2291 return rc;
2292}
+ Here is the call graph for this function:

◆ op_envelope_edit_headers()

static int op_envelope_edit_headers ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit the message with headers - Implements compose_function_t -.

Definition at line 2299 of file functions.c.

2301{
2302 struct ComposeSharedData *shared = fdata->shared;
2304 const char *tag = NULL;
2305 char *err = NULL;
2306 mutt_env_to_local(shared->email->env);
2307 const char *const c_editor = cs_subset_string(shared->sub, "editor");
2308 if (shared->email->body->type == TYPE_MULTIPART)
2309 {
2310 struct Body *b = shared->email->body->parts;
2311 while (b && b->parts)
2312 b = b->parts;
2313 if (b)
2314 mutt_edit_headers(NONULL(c_editor), b->filename, shared->email, shared->fcc);
2315 }
2316 else
2317 {
2318 mutt_edit_headers(NONULL(c_editor), shared->email->body->filename,
2319 shared->email, shared->fcc);
2320 }
2321
2322 if (mutt_env_to_intl(shared->email->env, &tag, &err))
2323 {
2324 mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
2325 FREE(&err);
2326 }
2328
2330 mutt_update_encoding(shared->email->body, shared->sub);
2331
2332 /* attachments may have been added */
2333 if (shared->adata->actx->idxlen &&
2334 shared->adata->actx->idx[shared->adata->actx->idxlen - 1]->body->next)
2335 {
2337 update_menu(shared->adata->actx, shared->adata->menu, true);
2338 }
2339
2341 /* Unconditional hook since editor was invoked */
2342 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2343 return FR_SUCCESS;
2344}
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition attach.c:162
void mutt_edit_headers(const char *editor, const char *body, struct Email *e, struct Buffer *fcc)
Let the user edit the message header and body.
Definition header.c:181
@ NT_EMAIL_CHANGE_ENVELOPE
Email's Envelope has changed.
Definition email.h:187
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope's Address fields to Punycode format.
Definition envelope.c:350
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope's Address fields to local format.
Definition envelope.c:316
void mutt_rfc3676_space_unstuff(struct Email *e)
Remove RFC3676 space stuffing.
Definition rfc3676.c:503
void mutt_rfc3676_space_stuff(struct Email *e)
Perform RFC3676 space stuffing on an Email.
Definition rfc3676.c:490
struct Buffer * fcc
Buffer to save FCC.
Definition shared_data.h:44
struct Envelope * env
Envelope information.
Definition email.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ op_compose_edit_file()

static int op_compose_edit_file ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit the file to be attached - Implements compose_function_t -.

Definition at line 2349 of file functions.c.

2350{
2351 struct ComposeSharedData *shared = fdata->shared;
2352 if (!check_count(shared->adata->actx))
2353 return FR_ERROR;
2354 struct AttachPtr *cur_att = current_attachment(shared->adata->actx,
2355 shared->adata->menu);
2356 if (cur_att->body->type == TYPE_MULTIPART)
2357 {
2358 mutt_error(_("Can't edit multipart attachments"));
2359 return FR_ERROR;
2360 }
2361 const char *const c_editor = cs_subset_string(shared->sub, "editor");
2362 mutt_edit_file(NONULL(c_editor), cur_att->body->filename);
2363 mutt_update_encoding(cur_att->body, shared->sub);
2366 /* Unconditional hook since editor was invoked */
2367 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2368 return FR_SUCCESS;
2369}
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition curs_lib.c:118
+ Here is the call graph for this function:

◆ op_compose_edit_message()

static int op_compose_edit_message ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Edit the message - Implements compose_function_t -.

Definition at line 2374 of file functions.c.

2376{
2377 struct ComposeSharedData *shared = fdata->shared;
2378 const bool c_edit_headers = cs_subset_bool(shared->sub, "edit_headers");
2379 if (!c_edit_headers)
2380 {
2382 const char *const c_editor = cs_subset_string(shared->sub, "editor");
2383 mutt_edit_file(c_editor, shared->email->body->filename);
2385 mutt_update_encoding(shared->email->body, shared->sub);
2387 /* Unconditional hook since editor was invoked */
2388 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2389 return FR_SUCCESS;
2390 }
2391
2392 return op_envelope_edit_headers(fdata, event);
2393}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
static int op_envelope_edit_headers(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit the message with headers - Implements compose_function_t -.
Definition functions.c:2299
+ Here is the call graph for this function:

◆ op_compose_ispell()

static int op_compose_ispell ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Run ispell on the message - Implements compose_function_t -.

Definition at line 2398 of file functions.c.

2399{
2400 struct ComposeSharedData *shared = fdata->shared;
2401 endwin();
2402 const char *const c_ispell = cs_subset_string(shared->sub, "ispell");
2403 struct Buffer *cmd = buf_pool_get();
2404 struct Buffer *quoted = buf_pool_get();
2405 buf_quote_filename(quoted, shared->email->body->filename, true);
2406 buf_printf(cmd, "%s -x %s", NONULL(c_ispell), buf_string(quoted));
2407 buf_pool_release(&quoted);
2408 if (mutt_system(buf_string(cmd)) == -1)
2409 {
2410 mutt_error(_("Error running \"%s\""), buf_string(cmd));
2411 buf_pool_release(&cmd);
2412 return FR_ERROR;
2413 }
2414 buf_pool_release(&cmd);
2415
2416 mutt_update_encoding(shared->email->body, shared->sub);
2418 return FR_SUCCESS;
2419}
void buf_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell's quoting rules.
Definition file.c:803
int mutt_system(const char *cmd)
Run an external command.
Definition system.c:51
int endwin(void)
+ Here is the call graph for this function:

◆ op_compose_postpone_message()

static int op_compose_postpone_message ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Save this message to send later - Implements compose_function_t -.

Definition at line 2424 of file functions.c.

2426{
2427 struct ComposeSharedData *shared = fdata->shared;
2428 if (check_attachments(shared->adata->actx, shared->sub) != 0)
2429 {
2431 return FR_ERROR;
2432 }
2433
2434 shared->rc = 1;
2435 return FR_DONE;
2436}
static int check_attachments(struct AttachCtx *actx, struct ConfigSubset *sub)
Check if any attachments have changed or been deleted.
Definition functions.c:309
@ FR_DONE
Exit the Dialog.
Definition dispatcher.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ op_compose_rename_file()

static int op_compose_rename_file ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Rename/move an attached file - Implements compose_function_t -.

Definition at line 2441 of file functions.c.

2443{
2444 struct ComposeSharedData *shared = fdata->shared;
2445 if (!check_count(shared->adata->actx))
2446 return FR_ERROR;
2447 struct AttachPtr *cur_att = current_attachment(shared->adata->actx,
2448 shared->adata->menu);
2449 if (cur_att->body->type == TYPE_MULTIPART)
2450 {
2451 mutt_error(_("Can't rename multipart attachments"));
2452 return FR_ERROR;
2453 }
2454 struct Buffer *fname = buf_pool_get();
2455 buf_strcpy(fname, cur_att->body->filename);
2456 pretty_mailbox(fname);
2457 struct FileCompletionData cdata = { false, shared->mailbox, NULL, NULL, NULL };
2458 if ((mw_get_field(_("Rename to: "), fname, MUTT_COMP_NONE, HC_FILE,
2459 &CompleteFileOps, &cdata) == 0) &&
2460 !buf_is_empty(fname))
2461 {
2462 struct stat st = { 0 };
2463 if (stat(cur_att->body->filename, &st) == -1)
2464 {
2465 /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */
2466 mutt_error(_("Can't stat %s: %s"), buf_string(fname), strerror(errno));
2467 buf_pool_release(&fname);
2468 return FR_ERROR;
2469 }
2470
2471 expand_path(fname, false);
2472 if (mutt_file_rename(cur_att->body->filename, buf_string(fname)))
2473 {
2474 buf_pool_release(&fname);
2475 return FR_ERROR;
2476 }
2477
2478 mutt_str_replace(&cur_att->body->filename, buf_string(fname));
2480
2481 if (cur_att->body->stamp >= st.st_mtime)
2482 mutt_stamp_attachment(cur_att->body);
2483 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
2484 }
2485 buf_pool_release(&fname);
2486 return FR_SUCCESS;
2487}
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition file.c:1257
void mutt_stamp_attachment(struct Body *b)
Timestamp an Attachment.
Definition sendlib.c:409
time_t stamp
Time stamp of last encoding update.
Definition body.h:77
+ Here is the call graph for this function:

◆ op_compose_send_message()

static int op_compose_send_message ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Send the message - Implements compose_function_t -.

Definition at line 2492 of file functions.c.

2494{
2495 struct ComposeSharedData *shared = fdata->shared;
2496 /* Note: We don't invoke send2-hook here, since we want to leave
2497 * users an opportunity to change settings from the ":" prompt. */
2498 if (check_attachments(shared->adata->actx, shared->sub) != 0)
2499 {
2501 return FR_NO_ACTION;
2502 }
2503
2504 if (!shared->fcc_set && !buf_is_empty(shared->fcc))
2505 {
2506 enum QuadOption ans = query_quadoption(_("Save a copy of this message?"),
2507 shared->sub, "copy");
2508 if (ans == MUTT_ABORT)
2509 return FR_NO_ACTION;
2510 else if (ans == MUTT_NO)
2511 buf_reset(shared->fcc);
2512 }
2513
2514 shared->rc = 0;
2515 return FR_DONE;
2516}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
QuadOption
Possible values for a quad-option.
Definition quad.h:36
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition quad.h:37
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition quad.h:38
enum QuadOption query_quadoption(const char *prompt, struct ConfigSubset *sub, const char *name)
Ask the user a quad-question.
Definition question.c:384
bool fcc_set
User has edited the Fcc: field.
Definition shared_data.h:46
+ Here is the call graph for this function:

◆ op_compose_write_message()

static int op_compose_write_message ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Write the message to a folder - Implements compose_function_t -.

Definition at line 2521 of file functions.c.

2523{
2524 struct ComposeSharedData *shared = fdata->shared;
2525 int rc = FR_NO_ACTION;
2526 struct Buffer *fname = buf_pool_get();
2527 if (shared->mailbox)
2528 {
2529 buf_strcpy(fname, mailbox_path(shared->mailbox));
2530 pretty_mailbox(fname);
2531 }
2532 if (shared->adata->actx->idxlen)
2533 shared->email->body = shared->adata->actx->idx[0]->body;
2534 if ((mw_enter_fname(_("Write message to mailbox"), fname, true,
2535 shared->mailbox, false, NULL, NULL, MUTT_SEL_NONE) != -1) &&
2536 !buf_is_empty(fname))
2537 {
2538 mutt_message(_("Writing message to %s ..."), buf_string(fname));
2539 expand_path(fname, false);
2540
2541 if (shared->email->body->next)
2542 shared->email->body = mutt_make_multipart(shared->email->body);
2543
2544 if (mutt_write_fcc(buf_string(fname), shared->email, NULL, false, NULL,
2545 NULL, shared->sub) == 0)
2546 mutt_message(_("Message written"));
2547
2548 shared->email->body = mutt_remove_multipart(shared->email->body);
2549 rc = FR_SUCCESS;
2550 }
2551 buf_pool_release(&fname);
2552 return rc;
2553}
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition multipart.c:133
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition multipart.c:107
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, const char *fcc, char **finalpath, struct ConfigSubset *sub)
Write email to FCC mailbox.
Definition sendlib.c:1024
+ Here is the call graph for this function:

◆ op_display_headers()

static int op_display_headers ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Display message and toggle header weeding - Implements compose_function_t -.

This function handles:

  • OP_ATTACH_VIEW
  • OP_ATTACH_VIEW_MAILCAP
  • OP_ATTACH_VIEW_PAGER
  • OP_ATTACH_VIEW_TEXT
  • OP_DISPLAY_HEADERS

Definition at line 2565 of file functions.c.

2566{
2567 struct ComposeSharedData *shared = fdata->shared;
2568 if (!check_count(shared->adata->actx))
2569 return FR_ERROR;
2570
2571 enum ViewAttachMode mode = MUTT_VA_REGULAR;
2572
2573 const int op = event->op;
2574 switch (op)
2575 {
2576 case OP_ATTACH_VIEW:
2577 case OP_DISPLAY_HEADERS:
2578 break;
2579
2580 case OP_ATTACH_VIEW_MAILCAP:
2581 mode = MUTT_VA_MAILCAP;
2582 break;
2583
2584 case OP_ATTACH_VIEW_PAGER:
2585 mode = MUTT_VA_PAGER;
2586 break;
2587
2588 case OP_ATTACH_VIEW_TEXT:
2589 mode = MUTT_VA_AS_TEXT;
2590 break;
2591 }
2592
2593 if (mode == MUTT_VA_REGULAR)
2594 {
2595 mutt_attach_display_loop(shared->sub, shared->adata->menu, op,
2596 shared->email, shared->adata->actx, false);
2597 }
2598 else
2599 {
2600 struct AttachPtr *cur_att = current_attachment(shared->adata->actx,
2601 shared->adata->menu);
2602 mutt_view_attachment(NULL, cur_att->body, mode, shared->email,
2603 shared->adata->actx, shared->adata->menu->win);
2604 }
2605
2607 /* no send2hook, since this doesn't modify the message */
2608 return FR_SUCCESS;
2609}
int mutt_view_attachment(FILE *fp, struct Body *b, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
ViewAttachMode
Options for mutt_view_attachment()
Definition mutt_attach.h:44
@ MUTT_VA_MAILCAP
Force viewing using mailcap entry.
Definition mutt_attach.h:46
@ MUTT_VA_REGULAR
View using default method.
Definition mutt_attach.h:45
@ MUTT_VA_PAGER
View attachment in pager using copiousoutput mailcap.
Definition mutt_attach.h:48
@ MUTT_VA_AS_TEXT
Force viewing as text.
Definition mutt_attach.h:47
int mutt_attach_display_loop(struct ConfigSubset *sub, struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
Event loop for the Attachment menu.
Definition recvattach.c:917
struct MuttWindow * win
Window holding the Menu.
Definition lib.h:94
+ Here is the call graph for this function:

◆ op_exit()

static int op_exit ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Exit this menu - Implements compose_function_t -.

Definition at line 2614 of file functions.c.

2615{
2616 struct ComposeSharedData *shared = fdata->shared;
2617 enum QuadOption ans = query_quadoption(_("Save (postpone) draft message?"),
2618 shared->sub, "postpone");
2619 if (ans == MUTT_NO)
2620 {
2621 for (int i = 0; i < shared->adata->actx->idxlen; i++)
2622 if (shared->adata->actx->idx[i]->unowned)
2623 shared->adata->actx->idx[i]->body->unlink = false;
2624
2625 if (!(shared->flags & MUTT_COMPOSE_NOFREEHEADER))
2626 {
2627 for (int i = 0; i < shared->adata->actx->idxlen; i++)
2628 {
2629 /* avoid freeing other attachments */
2630 shared->adata->actx->idx[i]->body->next = NULL;
2631 if (!shared->adata->actx->idx[i]->body->email)
2632 shared->adata->actx->idx[i]->body->parts = NULL;
2633 mutt_body_free(&shared->adata->actx->idx[i]->body);
2634 }
2635 }
2636 shared->rc = -1;
2637 return FR_DONE;
2638 }
2639 else if (ans == MUTT_ABORT)
2640 {
2641 return FR_NO_ACTION;
2642 }
2643
2644 return op_compose_postpone_message(fdata, event);
2645}
#define MUTT_COMPOSE_NOFREEHEADER
Don't free the header when closing compose dialog.
Definition lib.h:55
static int op_compose_postpone_message(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Save this message to send later - Implements compose_function_t -.
Definition functions.c:2424
int flags
Flags, e.g. MUTT_COMPOSE_NOFREEHEADER.
Definition shared_data.h:45
+ Here is the call graph for this function:

◆ op_forget_passphrase()

static int op_forget_passphrase ( struct ComposeFunctionData * fdata,
const struct KeyEvent * event )
static

Wipe passphrases from memory - Implements compose_function_t -.

Definition at line 2650 of file functions.c.

2651{
2653 return FR_SUCCESS;
2654}
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition crypt.c:89
+ Here is the call graph for this function: