NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
recvattach.h File Reference

Routines for managing attachments. More...

#include <stdbool.h>
#include <stdio.h>
+ Include dependency graph for recvattach.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void mutt_attach_init (struct AttachCtx *actx)
 Create a new Attachment context.
 
void mutt_update_tree (struct AttachCtx *actx)
 Refresh the list of attachments.
 
void dlg_attach (struct ConfigSubset *sub, struct MailboxView *mv, struct Email *e, FILE *fp, bool attach_msg)
 Show the attachments in a Menu -.
 
void mutt_generate_recvattach_list (struct AttachCtx *actx, struct Email *e, struct Body *parts, FILE *fp, int parent_type, int level, bool decrypted)
 Create a list of attachments.
 
struct AttachPtrcurrent_attachment (struct AttachCtx *actx, struct Menu *menu)
 Get the current attachment.
 
void mutt_update_recvattach_menu (struct AttachCtx *actx, struct Menu *menu, bool init)
 Update the Attachment Menu.
 
void recvattach_edit_content_type (struct AttachCtx *actx, struct Menu *menu, struct Email *e)
 Edit the content type of an attachment.
 
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.
 
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.
 

Detailed Description

Routines for managing attachments.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file recvattach.h.

Function Documentation

◆ mutt_attach_init()

void mutt_attach_init ( struct AttachCtx * actx)

Create a new Attachment context.

Parameters
actxAttachment context

Definition at line 1154 of file recvattach.c.

1155{
1156 /* Collapse the attachments if '$digest_collapse' is set AND if...
1157 * the outer container is of type 'multipart/digest' */
1158 bool digest = mutt_istr_equal(actx->email->body->subtype, "digest");
1159
1160 const bool c_digest_collapse = cs_subset_bool(NeoMutt->sub, "digest_collapse");
1161 for (int i = 0; i < actx->idxlen; i++)
1162 {
1163 actx->idx[i]->body->tagged = false;
1164
1165 /* OR an inner container is of type 'multipart/digest' */
1166 actx->idx[i]->collapsed = (c_digest_collapse &&
1167 (digest ||
1168 ((actx->idx[i]->body->type == TYPE_MULTIPART) &&
1169 mutt_istr_equal(actx->idx[i]->body->subtype, "digest"))));
1170 }
1171}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:677
struct Email * email
Used by recvattach for updating.
Definition attach.h:66
struct AttachPtr ** idx
Array of attachments.
Definition attach.h:69
short idxlen
Number of attachmentes.
Definition attach.h:70
struct Body * body
Attachment.
Definition attach.h:37
bool collapsed
Group is collapsed.
Definition attach.h:45
bool tagged
This attachment is tagged.
Definition body.h:90
char * subtype
content-type subtype
Definition body.h:61
unsigned int type
content-type primary type, ContentType
Definition body.h:40
struct Body * body
List of MIME parts.
Definition email.h:69
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_update_tree()

void mutt_update_tree ( struct AttachCtx * actx)

Refresh the list of attachments.

Parameters
actxAttachment context

Definition at line 116 of file recvattach.c.

117{
118 char buf[256] = { 0 };
119 char *s = NULL;
120
121 mutt_update_v2r(actx);
122
123 for (int vindex = 0; vindex < actx->vcount; vindex++)
124 {
125 const int rindex = actx->v2r[vindex];
126 actx->idx[rindex]->num = vindex;
127 if ((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf))
128 {
129 if (actx->idx[rindex]->level)
130 {
131 s = buf + 2 * (actx->idx[rindex]->level - 1);
132 *s++ = (actx->idx[rindex]->body->next) ? MUTT_TREE_LTEE : MUTT_TREE_LLCORNER;
133 *s++ = MUTT_TREE_HLINE;
134 *s++ = MUTT_TREE_RARROW;
135 }
136 else
137 {
138 s = buf;
139 }
140 *s = '\0';
141 }
142
143 if (actx->idx[rindex]->tree)
144 {
145 if (!mutt_str_equal(actx->idx[rindex]->tree, buf))
146 mutt_str_replace(&actx->idx[rindex]->tree, buf);
147 }
148 else
149 {
150 actx->idx[rindex]->tree = mutt_str_dup(buf);
151 }
152
153 if (((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf)) &&
154 actx->idx[rindex]->level)
155 {
156 s = buf + 2 * (actx->idx[rindex]->level - 1);
157 *s++ = (actx->idx[rindex]->body->next) ? MUTT_TREE_VLINE : MUTT_TREE_SPACE;
158 *s++ = MUTT_TREE_SPACE;
159 }
160 }
161}
@ MUTT_TREE_LLCORNER
Lower left corner.
Definition thread.h:57
@ MUTT_TREE_RARROW
Right arrow.
Definition thread.h:63
@ MUTT_TREE_LTEE
Left T-piece.
Definition thread.h:59
@ MUTT_TREE_VLINE
Vertical line.
Definition thread.h:61
@ MUTT_TREE_HLINE
Horizontal line.
Definition thread.h:60
@ MUTT_TREE_SPACE
Blank space.
Definition thread.h:62
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
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
static void mutt_update_v2r(struct AttachCtx *actx)
Update the virtual list of attachments.
Definition recvattach.c:85
short vcount
The number of virtual attachments.
Definition attach.h:74
short * v2r
Mapping from virtual to real attachment.
Definition attach.h:73
char * tree
Tree characters to display.
Definition attach.h:40
int num
Attachment index number.
Definition attach.h:42
int level
Nesting depth of attachment.
Definition attach.h:41
struct Body * next
next attachment in the list
Definition body.h:72
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_generate_recvattach_list()

void mutt_generate_recvattach_list ( struct AttachCtx * actx,
struct Email * e,
struct Body * b,
FILE * fp,
int parent_type,
int level,
bool decrypted )

Create a list of attachments.

Parameters
actxAttachment context
eEmail
bBody of email
fpFile to read from
parent_typeType, e.g. TYPE_MULTIPART
levelAttachment depth
decryptedTrue if attachment has been decrypted

Definition at line 1056 of file recvattach.c.

1059{
1060 struct Body *bp = NULL;
1061 struct Body *new_body = NULL;
1062 FILE *fp_new = NULL;
1064
1065 for (bp = b; bp; bp = bp->next)
1066 {
1067 bool need_secured = false;
1068 bool secured = false;
1069
1071 {
1072 need_secured = true;
1073
1074 if (type & SEC_ENCRYPT)
1075 {
1077 goto decrypt_failed;
1078
1079 if (e->env)
1081 }
1082
1083 secured = (crypt_smime_decrypt_mime(fp, &fp_new, bp, &new_body) == 0);
1084 /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1085 * text/plain type will still be returned by mutt_read_mime_header().
1086 * We can't distinguish an actual part from a failure, so only use a
1087 * text/plain that results from a single top-level part. */
1088 if (secured && (new_body->type == TYPE_TEXT) &&
1089 mutt_istr_equal("plain", new_body->subtype) && ((b != bp) || bp->next))
1090 {
1091 mutt_body_free(&new_body);
1092 mutt_file_fclose(&fp_new);
1093 goto decrypt_failed;
1094 }
1095
1096 if (secured && (type & SEC_ENCRYPT))
1097 e->security |= SMIME_ENCRYPT;
1098 }
1099
1100 if (((WithCrypto & APPLICATION_PGP) != 0) &&
1102 {
1103 need_secured = true;
1104
1106 goto decrypt_failed;
1107
1108 secured = (crypt_pgp_decrypt_mime(fp, &fp_new, bp, &new_body) == 0);
1109
1110 if (secured)
1111 e->security |= PGP_ENCRYPT;
1112 }
1113
1114 if (need_secured && secured)
1115 {
1116 mutt_actx_add_fp(actx, fp_new);
1117 mutt_actx_add_body(actx, new_body);
1118 mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1119 continue;
1120 }
1121
1122 decrypt_failed:
1123 /* Fall through and show the original parts if decryption fails */
1124 if (need_secured && !secured)
1125 mutt_error(_("Can't decrypt encrypted message"));
1126
1127 struct AttachPtr *ap = mutt_aptr_new();
1128 mutt_actx_add_attach(actx, ap);
1129
1130 ap->body = bp;
1131 ap->fp = fp;
1132 bp->aptr = ap;
1134 ap->level = level;
1135 ap->decrypted = decrypted;
1136
1137 if (mutt_is_message_type(bp->type, bp->subtype))
1138 {
1139 mutt_generate_recvattach_list(actx, bp->email, bp->parts, fp, bp->type,
1140 level + 1, decrypted);
1141 e->security |= bp->email->security;
1142 }
1143 else
1144 {
1145 mutt_generate_recvattach_list(actx, e, bp->parts, fp, bp->type, level + 1, decrypted);
1146 }
1147 }
1148}
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition attach.c:65
void mutt_actx_add_fp(struct AttachCtx *actx, FILE *fp_new)
Save a File handle to the Attachment Context.
Definition attach.c:121
struct AttachPtr * mutt_aptr_new(void)
Create a new Attachment Pointer.
Definition attach.c:40
void mutt_actx_add_body(struct AttachCtx *actx, struct Body *b)
Add an email body to an Attachment Context.
Definition attach.c:142
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition crypt.c:609
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition crypt.c:131
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition crypt.c:443
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition crypt.c:504
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition cryptglue.c:237
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition cryptglue.c:538
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition cryptglue.c:510
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition parse.c:1556
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_error(...)
Definition logging2.h:94
@ TYPE_TEXT
Type: 'text/*'.
Definition mime.h:38
#define _(a)
Definition message.h:28
uint16_t SecurityFlags
Definition lib.h:104
@ SEC_ENCRYPT
Email is encrypted.
Definition lib.h:92
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:106
#define PGP_ENCRYPT
Email is PGP encrypted.
Definition lib.h:112
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:107
#define SMIME_ENCRYPT
Email is S/MIME encrypted.
Definition lib.h:118
#define WithCrypto
Definition lib.h:132
void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *b, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
An email to which things will be attached.
Definition attach.h:36
FILE * fp
Used in the recvattach menu.
Definition attach.h:38
bool decrypted
Not part of message as stored in the email->body.
Definition attach.h:44
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition attach.h:39
The body of an email.
Definition body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition body.h:75
struct Email * email
header information for message/rfc822
Definition body.h:74
struct Envelope * env
Envelope information.
Definition email.h:68
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ current_attachment()

struct AttachPtr * current_attachment ( struct AttachCtx * actx,
struct Menu * menu )

Get the current attachment.

Parameters
actxAttachment context
menuMenu
Return values
ptrCurrent Attachment

Definition at line 71 of file recvattach.c.

72{
73 const int virt = menu_get_index(menu);
74 const int index = actx->v2r[virt];
75
76 return actx->idx[index];
77}
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition menu.c:155
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_update_recvattach_menu()

void mutt_update_recvattach_menu ( struct AttachCtx * actx,
struct Menu * menu,
bool init )

Update the Attachment Menu.

Parameters
actxAttachment context
menuMenu listing Attachments
initIf true, create a new Attachments context

Definition at line 1179 of file recvattach.c.

1180{
1181 if (init)
1182 {
1183 mutt_generate_recvattach_list(actx, actx->email, actx->email->body,
1184 actx->fp_root, -1, 0, 0);
1185 mutt_attach_init(actx);
1186 }
1187
1188 mutt_update_tree(actx);
1189
1190 menu->max = actx->vcount;
1191
1192 const int index = menu_get_index(menu);
1193 if (index >= menu->max)
1194 menu_set_index(menu, menu->max - 1);
1196}
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
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition menu.c:169
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition recvattach.c:116
FILE * fp_root
Used by recvattach for updating.
Definition attach.h:67
int max
Number of entries in the menu.
Definition lib.h:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recvattach_edit_content_type()

void recvattach_edit_content_type ( struct AttachCtx * actx,
struct Menu * menu,
struct Email * e )

Edit the content type of an attachment.

Parameters
actxAttachment context
menuMenu listing Attachments
eEmail

Definition at line 887 of file recvattach.c.

888{
889 struct AttachPtr *cur_att = current_attachment(actx, menu);
890 if (!mutt_edit_content_type(e, cur_att->body, cur_att->fp))
891 return;
892
893 /* The mutt_update_recvattach_menu() will overwrite any changes
894 * made to a decrypted cur_att->body, so warn the user. */
895 if (cur_att->decrypted)
896 {
897 mutt_message(_("Structural changes to decrypted attachments are not supported"));
898 mutt_sleep(1);
899 }
900 /* Editing the content type can rewrite the body structure. */
901 for (int i = 0; i < actx->idxlen; i++)
902 actx->idx[i]->body = NULL;
904 mutt_update_recvattach_menu(actx, menu, true);
905}
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition attach.c:162
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition external.c:1073
#define mutt_message(...)
Definition logging2.h:93
void mutt_sleep(short s)
Sleep for a while.
Definition muttlib.c:787
void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition recvattach.c:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ aa_add_selection()

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.

Parameters
aaEmpty AttachPtrArray to populate
actxList of Attachments
menuMenu
use_taggedUse tagged attachments
countRepeat-count (0 or 1 == current selection)
Return values
numNumber of selected Attachments
-1Error

Definition at line 125 of file selection.c.

127{
128 if (!aa || !actx || !menu)
129 return -1;
130
131 if (use_tagged)
132 return aa_add_tagged(aa, actx);
133
134 const int index = menu_get_index(menu);
135 if ((index < 0) || (index >= actx->vcount))
136 return -1;
137
138 int n = (count > 1) ? count : 1;
139 if ((index + n) > actx->vcount)
140 n = actx->vcount - index;
141
142 for (int i = 0; i < n; i++)
143 {
144 const int rindex = actx->v2r[index + i];
145 if ((rindex < 0) || (rindex >= actx->idxlen))
146 return -1;
147
148 aa_add_folded(aa, actx, rindex);
149 }
150
151 return ARRAY_SIZE(aa);
152}
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
static int aa_add_tagged(struct AttachPtrArray *aa, struct AttachCtx *actx)
Get an array of tagged Attachments.
Definition selection.c:101
static void aa_add_folded(struct AttachPtrArray *aa, struct AttachCtx *actx, int rindex)
Add an Attachment, expanding collapsed children.
Definition selection.c:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ba_add_selection()

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.

Parameters
baEmpty BodyArray to populate
actxList of Attachments
menuMenu
use_taggedUse tagged attachments
countRepeat-count (0 or 1 == current selection)
Return values
numNumber of selected Attachments
-1Error

Definition at line 164 of file selection.c.

166{
167 if (!ba)
168 return -1;
169
170 struct AttachPtrArray aa = ARRAY_HEAD_INITIALIZER;
171 if (aa_add_selection(&aa, actx, menu, use_tagged, count) < 0)
172 {
173 ARRAY_FREE(&aa);
174 return -1;
175 }
176
177 struct AttachPtr **app = NULL;
178 ARRAY_FOREACH(app, &aa)
179 {
180 ARRAY_ADD(ba, (*app)->body);
181 }
182
183 const int rc = ARRAY_SIZE(ba);
184 ARRAY_FREE(&aa);
185 return rc;
186}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function: