From: Kevin McCarthy Date: Thu, 24 Oct 2019 06:46:06 +0000 (+0800) Subject: Convert fcc to a buffer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=79e85452079bf6f24d431151fcb72923a7a3f6ab;p=neomutt Convert fcc to a buffer This affects the send.c flow(ci_send_message()), the compose menu, and various helper functions. Upstream-commit: https://gitlab.com/muttmua/mutt/commit/c5d770ead5cd8444859dd4a785677aa1920454f0 Co-authored-by: Richard Russon --- diff --git a/compose.c b/compose.c index 3d8792ed5..b4a57d8f9 100644 --- a/compose.c +++ b/compose.c @@ -107,7 +107,7 @@ static void compose_status_line(char *buf, size_t buflen, size_t col, int cols, struct ComposeRedrawData { struct Email *email; - char *fcc; + struct Buffer *fcc; #ifdef USE_AUTOCRYPT enum AutocryptRec autocrypt_rec; int autocrypt_rec_override; @@ -660,7 +660,7 @@ static void draw_envelope_addr(int line, struct AddressList *al, struct ComposeR static void draw_envelope(struct ComposeRedrawData *rd) { struct Email *e = rd->email; - char *fcc = rd->fcc; + const char *fcc = mutt_b2s(rd->fcc); draw_envelope_addr(HDR_FROM, &e->env->from, rd); #ifdef USE_NNTP @@ -1085,14 +1085,13 @@ static void compose_status_line(char *buf, size_t buflen, size_t col, int cols, * mutt_compose_menu - Allow the user to edit the message envelope * @param e Email to fill * @param fcc Buffer to save FCC - * @param fcclen Length of FCC buffer * @param e_cur Current message * @param flags Flags, e.g. #MUTT_COMPOSE_NOFREEHEADER * @retval 1 Message should be postponed * @retval 0 Normal exit * @retval -1 Abort message */ -int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e_cur, int flags) +int mutt_compose_menu(struct Email *e, struct Buffer *fcc, struct Email *e_cur, int flags) { char helpstr[1024]; // This isn't copied by the help bar char buf[PATH_MAX]; @@ -1257,13 +1256,13 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e break; case OP_COMPOSE_EDIT_FCC: - mutt_str_strfcpy(buf, fcc, sizeof(buf)); - if (mutt_get_field(_("Fcc: "), buf, sizeof(buf), MUTT_FILE | MUTT_CLEAR) == 0) + mutt_buffer_strcpy(&fname, mutt_b2s(fcc)); + if (mutt_buffer_get_field(_("Fcc: "), &fname, MUTT_FILE | MUTT_CLEAR) == 0) { - mutt_str_strfcpy(fcc, buf, fcclen); - mutt_pretty_mailbox(fcc, fcclen); + mutt_buffer_strcpy(fcc, mutt_b2s(&fname)); + mutt_buffer_pretty_mailbox(fcc); mutt_window_move(menu->indexwin, HDR_FCC, HDR_XOFFSET); - mutt_paddstr(W, fcc); + mutt_paddstr(W, mutt_b2s(fcc)); fcc_set = true; } mutt_message_hook(NULL, e, MUTT_SEND2_HOOK); @@ -1290,7 +1289,7 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e const char *tag = NULL; char *err = NULL; mutt_env_to_local(e->env); - mutt_edit_headers(NONULL(C_Editor), e->content->filename, e, fcc, fcclen); + mutt_edit_headers(NONULL(C_Editor), e->content->filename, e, fcc); if (mutt_env_to_intl(e->env, &tag, &err)) { mutt_error(_("Bad IDN in '%s': '%s'"), tag, err); @@ -1865,14 +1864,14 @@ int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e break; #endif - if (!fcc_set && *fcc) + if (!fcc_set && !mutt_buffer_is_empty(fcc)) { enum QuadOption ans = query_quadoption(C_Copy, _("Save a copy of this message?")); if (ans == MUTT_ABORT) break; else if (ans == MUTT_NO) - *fcc = '\0'; + mutt_buffer_reset(fcc); } loop = false; diff --git a/compose.h b/compose.h index 386b2a722..8ac79d4cb 100644 --- a/compose.h +++ b/compose.h @@ -35,6 +35,6 @@ extern unsigned char C_Postpone; /* flags for mutt_compose_menu() */ #define MUTT_COMPOSE_NOFREEHEADER (1 << 0) -int mutt_compose_menu(struct Email *e, char *fcc, size_t fcclen, struct Email *e_cur, int flags); +int mutt_compose_menu(struct Email *e, struct Buffer *fcc, struct Email *e_cur, int flags); #endif /* MUTT_COMPOSE_H */ diff --git a/edit.c b/edit.c index f84408210..00735cff7 100644 --- a/edit.c +++ b/edit.c @@ -532,7 +532,7 @@ int mutt_builtin_editor(const char *path, struct Email *e_new, struct Email *e_c if (C_EditHeaders) { mutt_env_to_local(e_new->env); - mutt_edit_headers(NONULL(C_Visual), path, e_new, NULL, 0); + mutt_edit_headers(NONULL(C_Visual), path, e_new, NULL); if (mutt_env_to_intl(e_new->env, &tag, &err)) mutt_window_printf(_("Bad IDN in '%s': '%s'"), tag, err); /* tag is a statically allocated string and should not be freed */ diff --git a/hook.c b/hook.c index 5cf51435c..de247ed4e 100644 --- a/hook.c +++ b/hook.c @@ -681,12 +681,13 @@ void mutt_default_save(char *path, size_t pathlen, struct Email *e) /** * mutt_select_fcc - Select the FCC path for an email * @param path Buffer for the path - * @param pathlen Length of the buffer * @param e Email */ -void mutt_select_fcc(char *path, size_t pathlen, struct Email *e) +void mutt_select_fcc(struct Buffer *path, struct Email *e) { - if (addr_hook(path, pathlen, MUTT_FCC_HOOK, NULL, e) != 0) + mutt_buffer_alloc(path, PATH_MAX); + + if (addr_hook(path->data, path->dsize, MUTT_FCC_HOOK, NULL, e) != 0) { const struct Address *to = TAILQ_FIRST(&e->env->to); const struct Address *cc = TAILQ_FIRST(&e->env->cc); @@ -696,15 +697,18 @@ void mutt_select_fcc(char *path, size_t pathlen, struct Email *e) const struct Address *addr = to ? to : (cc ? cc : bcc); struct Buffer *buf = mutt_buffer_pool_get(); mutt_safe_path(buf, addr); - mutt_path_concat(path, NONULL(C_Folder), mutt_b2s(buf), pathlen); + mutt_buffer_concat_path(path, NONULL(C_Folder), mutt_b2s(buf)); mutt_buffer_pool_release(&buf); - if (!C_ForceName && (mx_access(path, W_OK) != 0)) - mutt_str_strfcpy(path, C_Record, pathlen); + if (!C_ForceName && (mx_access(mutt_b2s(path), W_OK) != 0)) + mutt_buffer_strcpy(path, C_Record); } else - mutt_str_strfcpy(path, C_Record, pathlen); + mutt_buffer_strcpy(path, C_Record); } - mutt_pretty_mailbox(path, pathlen); + else + mutt_buffer_fix_dptr(path); + + mutt_buffer_pretty_mailbox(path); } /** diff --git a/hook.h b/hook.h index 398515bdc..2ed99afb0 100644 --- a/hook.h +++ b/hook.h @@ -76,7 +76,7 @@ void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type); enum CommandResult mutt_parse_idxfmt_hook(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err); enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err); enum CommandResult mutt_parse_unhook(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err); -void mutt_select_fcc(char *path, size_t pathlen, struct Email *e); +void mutt_select_fcc(struct Buffer *path, struct Email *e); void mutt_startup_shutdown_hook(HookFlags type); void mutt_timeout_hook(void); diff --git a/mutt_header.c b/mutt_header.c index d918f3ef5..ebacfae30 100644 --- a/mutt_header.c +++ b/mutt_header.c @@ -163,10 +163,9 @@ int mutt_label_message(struct Mailbox *m, struct EmailList *el) * @param body File containing message body * @param e Email * @param fcc Buffer for the fcc field - * @param fcclen Length of buffer */ void mutt_edit_headers(const char *editor, const char *body, struct Email *e, - char *fcc, size_t fcclen) + struct Buffer *fcc) { char buf[1024]; const char *p = NULL; @@ -288,8 +287,8 @@ void mutt_edit_headers(const char *editor, const char *body, struct Email *e, p = mutt_str_skip_email_wsp(np->data + plen); if (*p) { - mutt_str_strfcpy(fcc, p, fcclen); - mutt_pretty_mailbox(fcc, fcclen); + mutt_buffer_strcpy(fcc, p); + mutt_buffer_pretty_mailbox(fcc); } keep = false; } diff --git a/mutt_header.h b/mutt_header.h index b672b8e11..0246cbc7a 100644 --- a/mutt_header.h +++ b/mutt_header.h @@ -29,7 +29,7 @@ struct Email; struct EmailList; struct Mailbox; -void mutt_edit_headers(const char *editor, const char *body, struct Email *e, char *fcc, size_t fcclen); +void mutt_edit_headers(const char *editor, const char *body, struct Email *e, struct Buffer *fcc); void mutt_label_hash_add(struct Mailbox *m, struct Email *e); void mutt_label_hash_remove(struct Mailbox *m, struct Email *e); int mutt_label_message(struct Mailbox *m, struct EmailList *el); diff --git a/postpone.c b/postpone.c index aac353487..1661c1323 100644 --- a/postpone.c +++ b/postpone.c @@ -286,13 +286,12 @@ static struct Email *select_msg(struct Context *ctx) * @param[in] hdr envelope/attachment info for recalled message * @param[out] cur if message was a reply, 'cur' is set to the message which 'hdr' is in reply to * @param[in] fcc fcc for the recalled message - * @param[in] fcclen max length of fcc * @retval -1 Error/no messages * @retval 0 Normal exit * @retval #SEND_REPLY Recalled message is a reply */ int mutt_get_postponed(struct Context *ctx, struct Email *hdr, - struct Email **cur, char *fcc, size_t fcclen) + struct Email **cur, struct Buffer *fcc) { if (!C_Postponed) return -1; @@ -386,8 +385,8 @@ int mutt_get_postponed(struct Context *ctx, struct Email *hdr, else if ((plen = mutt_str_startswith(np->data, "X-Mutt-Fcc:", CASE_IGNORE))) { p = mutt_str_skip_email_wsp(np->data + plen); - mutt_str_strfcpy(fcc, p, fcclen); - mutt_pretty_mailbox(fcc, fcclen); + mutt_buffer_strcpy(fcc, p); + mutt_buffer_pretty_mailbox(fcc); /* note that x-mutt-fcc was present. we do this because we want to add a * default fcc if the header was missing, but preserve the request of the diff --git a/protos.h b/protos.h index 58b5ea71b..d394d93a8 100644 --- a/protos.h +++ b/protos.h @@ -76,7 +76,7 @@ int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new, stru int mutt_enter_string(char *buf, size_t buflen, int col, CompletionFlags flags); int mutt_enter_string_full(char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, char ***files, int *numfiles, struct EnterState *state); -int mutt_get_postponed(struct Context *ctx, struct Email *hdr, struct Email **cur, char *fcc, size_t fcclen); +int mutt_get_postponed(struct Context *ctx, struct Email *hdr, struct Email **cur, struct Buffer *fcc); SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app); int mutt_num_postponed(struct Mailbox *m, bool force); int mutt_thread_set_flag(struct Email *e, int flag, bool bf, bool subthread); diff --git a/send.c b/send.c index fc9b84906..55cf05f42 100644 --- a/send.c +++ b/send.c @@ -1583,7 +1583,6 @@ static bool search_attach_keyword(char *filename) * save_fcc - Save an Email to a 'sent mail' folder * @param[in] e Email to save * @param[in] fcc Folder to save to (can be comma-separated list) - * @param[in] fcc_len Length of fcc buffer * @param[in] clear_content Cleartext content of Email * @param[in] pgpkeylist List of pgp keys * @param[in] flags Send mode, see #SendFlags @@ -1591,13 +1590,13 @@ static bool search_attach_keyword(char *filename) * @retval 0 Success * @retval -1 Error */ -static int save_fcc(struct Email *e, char *fcc, size_t fcc_len, struct Body *clear_content, +static int save_fcc(struct Email *e, struct Buffer *fcc, struct Body *clear_content, char *pgpkeylist, SendFlags flags, char **finalpath) { int rc = 0; struct Body *save_content = NULL; - mutt_expand_path(fcc, fcc_len); + mutt_buffer_expand_path(fcc); /* Don't save a copy when we are in batch-mode, and the FCC * folder is on an IMAP server: This would involve possibly lots @@ -1608,15 +1607,16 @@ static int save_fcc(struct Email *e, char *fcc, size_t fcc_len, struct Body *cle * I'd like to think a bit more about this before including it. */ #ifdef USE_IMAP - if ((flags & SEND_BATCH) && (fcc[0] != '\0') && (imap_path_probe(fcc, NULL) == MUTT_IMAP)) + if ((flags & SEND_BATCH) && !mutt_buffer_is_empty(fcc) && + (imap_path_probe(mutt_b2s(fcc), NULL) == MUTT_IMAP)) { - fcc[0] = '\0'; + mutt_buffer_reset(fcc); mutt_error(_("Fcc to an IMAP mailbox is not supported in batch mode")); return rc; } #endif - if (!(*fcc && mutt_str_strcmp("/dev/null", fcc))) + if (mutt_buffer_is_empty(fcc) || (mutt_str_strcmp("/dev/null", mutt_b2s(fcc)) == 0)) return rc; struct Body *tmpbody = e->content; @@ -1682,7 +1682,7 @@ full_fcc: * the From_ line contains the current time instead of when the * message was first postponed. */ e->received = mutt_date_epoch(); - rc = mutt_write_multiple_fcc(fcc, e, NULL, false, NULL, finalpath); + rc = mutt_write_multiple_fcc(mutt_b2s(fcc), e, NULL, false, NULL, finalpath); while (rc && !(flags & SEND_BATCH)) { mutt_clear_error(); @@ -1701,8 +1701,8 @@ full_fcc: case 2: /* alternate (m)ailbox */ /* L10N: This is the prompt to enter an "alternate (m)ailbox" when the initial Fcc fails. */ - rc = mutt_enter_fname(_("Fcc mailbox"), fcc, fcc_len, true); - if ((rc == -1) || (fcc[0] == '\0')) + rc = mutt_buffer_enter_fname(_("Fcc mailbox"), fcc, true); + if ((rc == -1) || mutt_buffer_is_empty(fcc)) { rc = 0; break; @@ -1710,7 +1710,7 @@ full_fcc: /* fall through */ case 1: /* (r)etry */ - rc = mutt_write_multiple_fcc(fcc, e, NULL, false, NULL, finalpath); + rc = mutt_write_multiple_fcc(mutt_b2s(fcc), e, NULL, false, NULL, finalpath); break; case -1: /* abort */ @@ -1758,7 +1758,8 @@ full_fcc: * @retval 0 Success * @retval -1 Error */ -static int postpone_message(struct Email *e_post, struct Email *e_cur, char *fcc, SendFlags flags) +static int postpone_message(struct Email *e_post, struct Email *e_cur, + const char *fcc, SendFlags flags) { char *pgpkeylist = NULL; char *encrypt_as = NULL; @@ -1863,7 +1864,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile struct Context *ctx, struct EmailList *el) { char buf[1024]; - char fcc[PATH_MAX] = { 0 }; /* where to copy this message */ + struct Buffer fcc = mutt_buffer_make(0); /* where to copy this message */ FILE *fp_tmp = NULL; struct Body *pbody = NULL; int i; @@ -1909,6 +1910,10 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile flags |= SEND_POSTPONED; } + /* Allocate the buffer due to the long lifetime, but + * pre-resize it to ensure there are no NULL data field issues */ + mutt_buffer_alloc(&fcc, 1024); + if (flags & SEND_POSTPONED) { if (WithCrypto & APPLICATION_PGP) @@ -1927,7 +1932,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile if (flags == SEND_POSTPONED) { - rc = mutt_get_postponed(ctx, e_templ, &e_cur, fcc, sizeof(fcc)); + rc = mutt_get_postponed(ctx, e_templ, &e_cur, &fcc); if (rc < 0) { flags = SEND_POSTPONED; @@ -2215,7 +2220,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile else if (C_EditHeaders) { mutt_env_to_local(e_templ->env); - mutt_edit_headers(C_Editor, e_templ->content->filename, e_templ, fcc, sizeof(fcc)); + mutt_edit_headers(C_Editor, e_templ->content->filename, e_templ, &fcc); mutt_env_to_intl(e_templ->env, NULL, NULL); } else @@ -2369,7 +2374,8 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile /* specify a default fcc. if we are in batchmode, only save a copy of * the message if the value of $copy is yes or ask-yes */ - if (!fcc[0] && !(flags & SEND_POSTPONED_FCC) && (!(flags & SEND_BATCH) || (C_Copy & 0x1))) + if (mutt_buffer_is_empty(&fcc) && !(flags & SEND_POSTPONED_FCC) && + (!(flags & SEND_BATCH) || (C_Copy & 0x1))) { /* set the default FCC */ const bool killfrom = TAILQ_EMPTY(&e_templ->env->from); @@ -2377,7 +2383,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile { mutt_addrlist_append(&e_templ->env->from, mutt_default_from()); } - mutt_select_fcc(fcc, sizeof(fcc), e_templ); + mutt_select_fcc(&fcc, e_templ); if (killfrom) { mutt_addrlist_clear(&e_templ->env->from); @@ -2392,8 +2398,8 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile { main_loop: - mutt_pretty_mailbox(fcc, sizeof(fcc)); - i = mutt_compose_menu(e_templ, fcc, sizeof(fcc), e_cur, + mutt_buffer_pretty_mailbox(&fcc); + i = mutt_compose_menu(e_templ, &fcc, e_cur, ((flags & SEND_NO_FREE_HEADER) ? MUTT_COMPOSE_NOFREEHEADER : 0)); if (i == -1) { @@ -2408,7 +2414,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile } else if (i == 1) { - if (postpone_message(e_templ, e_cur, fcc, flags) != 0) + if (postpone_message(e_templ, e_cur, mutt_b2s(&fcc), flags) != 0) goto main_loop; mutt_message(_("Message postponed")); rc = 1; @@ -2540,7 +2546,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile mutt_prepare_envelope(e_templ->env, true); if (C_FccBeforeSend) - save_fcc(e_templ, fcc, sizeof(fcc), clear_content, pgpkeylist, flags, &finalpath); + save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath); i = send_message(e_templ); if (i < 0) @@ -2580,7 +2586,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile } if (!C_FccBeforeSend) - save_fcc(e_templ, fcc, sizeof(fcc), clear_content, pgpkeylist, flags, &finalpath); + save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath); if (!OptNoCurses && !(flags & SEND_MAILX)) { @@ -2616,6 +2622,7 @@ int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile rc = 0; cleanup: + mutt_buffer_dealloc(&fcc); if (flags & SEND_POSTPONED) { diff --git a/sendlib.c b/sendlib.c index 965d5db4e..56b55d2c8 100644 --- a/sendlib.c +++ b/sendlib.c @@ -3242,7 +3242,7 @@ int mutt_write_multiple_fcc(const char *path, struct Email *e, const char *msgid * @retval -1 Failure */ int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, - bool post, char *fcc, char **finalpath) + bool post, const char *fcc, char **finalpath) { struct Message *msg = NULL; char tempfile[PATH_MAX]; diff --git a/sendlib.h b/sendlib.h index 7b0a26bef..7123045f2 100644 --- a/sendlib.h +++ b/sendlib.h @@ -81,7 +81,7 @@ void mutt_stamp_attachment(struct Body *a); void mutt_unprepare_envelope(struct Envelope *env); void mutt_update_encoding(struct Body *a); void mutt_write_addrlist(struct AddressList *addr, FILE *fp, int linelen, bool display); -int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath); +int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, const char *fcc, char **finalpath); int mutt_write_mime_body(struct Body *a, FILE *fp); int mutt_write_mime_header(struct Body *a, FILE *fp); int mutt_write_multiple_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath);