int mutt_get_password (char *msg, char *buf, size_t buflen) { int rc; CLEARLINE (LINES-1); addstr (msg); rc = mutt_enter_string ((unsigned char *) buf, buflen, LINES - 1, mutt_strlen (msg), M_PASS); CLEARLINE (LINES-1); return (rc); }
int _mutt_get_field (/* const */ char *field, char *buf, size_t buflen, int complete, int multiple, char ***files, int *numfiles) { int ret; int len = mutt_strlen (field); /* in case field==buffer */ do { CLEARLINE (LINES-1); addstr (field); mutt_refresh (); ret = _mutt_enter_string ((unsigned char *) buf, buflen, LINES-1, len, complete, multiple, files, numfiles); } while (ret == 1); CLEARLINE (LINES-1); return (ret); }
int mutt_yesorno (const char *msg, int def) { event_t ch; unsigned char *yes = (unsigned char *) _("yes"); unsigned char *no = (unsigned char *) _("no"); CLEARLINE(LINES-1); printw("%s ([%c]/%c): ", msg, def ? *yes : *no, def ? *no : *yes); FOREVER { mutt_refresh (); ch = mutt_getch (); if (ch.ch == -1) return(-1); if (CI_is_return (ch.ch)) break; else if (tolower(ch.ch) == tolower(*yes)) { def = 1; break; } else if (tolower(ch.ch) == tolower(*no)) { def = 0; break; } else { BEEP(); } } addstr ((char *) (def ? yes : no)); mutt_refresh (); return (def); }
void mutt_show_error (void) { if (option (OPTKEEPQUIET)) return; SETCOLOR (option (OPTMSGERR) ? MT_COLOR_ERROR : MT_COLOR_MESSAGE); CLEARLINE (LINES-1); addstr (Errorbuf); SETCOLOR (MT_COLOR_NORMAL); }
/* returns 1 if OK to proceed, 0 to abort */ int mutt_save_confirm (const char *s, struct stat *st) { char tmp[_POSIX_PATH_MAX]; int ret = 1; int magic = 0; magic = mx_get_magic (s); if (stat (s, st) != -1) { if (magic == -1) { mutt_error (_("%s is not a mailbox!"), s); return 0; } if (option (OPTCONFIRMAPPEND)) { snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s); if (mutt_yesorno (tmp, 1) < 1) ret = 0; } } else { #ifdef USE_IMAP if (magic != M_IMAP) #endif /* execute the block unconditionally if we don't use imap */ { st->st_mtime = 0; st->st_atime = 0; if (errno == ENOENT) { if (option (OPTCONFIRMCREATE)) { snprintf (tmp, sizeof (tmp), _("Create %s?"), s); if (mutt_yesorno (tmp, 1) < 1) ret = 0; } } else { mutt_perror (s); return 0; } } } CLEARLINE (LINES-1); return (ret); }
void mutt_endwin (const char *msg) { if (!option (OPTNOCURSES)) { CLEARLINE (LINES - 1); attrset (A_NORMAL); mutt_refresh (); endwin (); } if (msg && *msg) puts (msg); }
/* invoke a command in a subshell */ void mutt_shell_escape (void) { char buf[LONG_STRING]; buf[0] = 0; if (mutt_get_field (_("Shell command: "), buf, sizeof (buf), M_CMD) == 0) { if (!buf[0] && Shell) strfcpy (buf, Shell, sizeof (buf)); if(buf[0]) { CLEARLINE (LINES-1); mutt_endwin (NULL); fflush (stdout); if (mutt_system (buf) != 0 || option (OPTWAITKEY)) mutt_any_key_to_continue (NULL); } } }
int query_quadoption (int opt, const char *prompt) { int v = quadoption (opt); switch (v) { case M_YES: case M_NO: return (v); default: v = mutt_yesorno (prompt, (v == M_ASKYES)); #ifndef LIBMUTT CLEARLINE (LINES - 1); #endif return (v); } /* not reached */ }
int _mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, int buffy, int multiple, char ***files, int *numfiles) { event_t ch; mvaddstr (LINES-1, 0, (char *) prompt); addstr (_(" ('?' for list): ")); if (buf[0]) addstr (buf); clrtoeol (); mutt_refresh (); ch = mutt_getch(); if (ch.ch == -1) { CLEARLINE (LINES-1); return (-1); } else if (ch.ch == '?') { mutt_refresh (); buf[0] = 0; _mutt_select_file (buf, blen, 0, multiple, files, numfiles); *redraw = REDRAW_FULL; } else { char *pc = safe_malloc (mutt_strlen (prompt) + 3); sprintf (pc, "%s: ", prompt); mutt_ungetch (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0); if (_mutt_get_field (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR, multiple, files, numfiles) != 0) buf[0] = 0; MAYBE_REDRAW (*redraw); FREE (&pc); } return 0; }
int mutt_multi_choice (char *prompt, char *letters) { event_t ch; int choice; char *p; mvaddstr (LINES - 1, 0, prompt); clrtoeol (); FOREVER { mutt_refresh (); ch = mutt_getch (); if (ch.ch == -1 || CI_is_return (ch.ch)) { choice = -1; break; } else { p = strchr (letters, ch.ch); if (p) { choice = p - letters + 1; break; } else if (ch.ch <= '9' && ch.ch > '0') { choice = ch.ch - '0'; if (choice <= mutt_strlen (letters)) break; } } BEEP (); } CLEARLINE (LINES - 1); mutt_refresh (); return choice; }
/* return values: * * 1 message should be postponed * 0 normal exit * -1 abort message */ int mutt_compose_menu (HEADER *msg, /* structure for new message */ char *fcc, /* where to save a copy of the message */ size_t fcclen, HEADER *cur, /* current message */ int flags) { char helpstr[LONG_STRING]; char buf[LONG_STRING]; char fname[_POSIX_PATH_MAX]; MUTTMENU *menu; ATTACHPTR **idx = NULL; short idxlen = 0; short idxmax = 0; int i, close = 0; int r = -1; /* return value */ int op = 0; int loop = 1; int fccSet = 0; /* has the user edited the Fcc: field ? */ CONTEXT *ctx = NULL, *this = NULL; /* Sort, SortAux could be changed in mutt_index_menu() */ int oldSort, oldSortAux; struct stat st; mutt_attach_init (msg->content); idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); menu = mutt_new_menu (MENU_COMPOSE); menu->offset = HDR_ATTACH; menu->max = idxlen; menu->make_entry = snd_entry; menu->tag = mutt_tag_attach; menu->data = idx; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, ComposeHelp); while (loop) { switch (op = mutt_menuLoop (menu)) { case OP_REDRAW: draw_envelope (msg, fcc); menu->offset = HDR_ATTACH; menu->pagelen = LINES - HDR_ATTACH - 2; break; case OP_COMPOSE_EDIT_FROM: menu->redraw = edit_address_list (HDR_FROM, &msg->env->from); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_TO: menu->redraw = edit_address_list (HDR_TO, &msg->env->to); if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) { crypt_opportunistic_encrypt (msg); redraw_crypt_lines (msg); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_BCC: menu->redraw = edit_address_list (HDR_BCC, &msg->env->bcc); if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) { crypt_opportunistic_encrypt (msg); redraw_crypt_lines (msg); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_CC: menu->redraw = edit_address_list (HDR_CC, &msg->env->cc); if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) { crypt_opportunistic_encrypt (msg); redraw_crypt_lines (msg); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_SUBJECT: if (msg->env->subject) strfcpy (buf, msg->env->subject, sizeof (buf)); else buf[0] = 0; if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0) { mutt_str_replace (&msg->env->subject, buf); move (HDR_SUBJECT, HDR_XOFFSET); if (msg->env->subject) mutt_paddstr (W, msg->env->subject); else clrtoeol(); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_REPLY_TO: menu->redraw = edit_address_list (HDR_REPLYTO, &msg->env->reply_to); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_FCC: strfcpy (buf, fcc, sizeof (buf)); if (mutt_get_field ("Fcc: ", buf, sizeof (buf), M_FILE | M_CLEAR) == 0) { strfcpy (fcc, buf, fcclen); mutt_pretty_mailbox (fcc, fcclen); move (HDR_FCC, HDR_XOFFSET); mutt_paddstr (W, fcc); fccSet = 1; } MAYBE_REDRAW (menu->redraw); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_MESSAGE: if (Editor && (mutt_strcmp ("builtin", Editor) != 0) && !option (OPTEDITHDRS)) { mutt_edit_file (Editor, msg->content->filename); mutt_update_encoding (msg->content); menu->redraw = REDRAW_FULL; mutt_message_hook (NULL, msg, M_SEND2HOOK); break; } /* fall through */ case OP_COMPOSE_EDIT_HEADERS: if (mutt_strcmp ("builtin", Editor) != 0 && (op == OP_COMPOSE_EDIT_HEADERS || (op == OP_COMPOSE_EDIT_MESSAGE && option (OPTEDITHDRS)))) { char *tag = NULL, *err = NULL; mutt_env_to_local (msg->env); mutt_edit_headers (NONULL (Editor), msg->content->filename, msg, fcc, fcclen); if (mutt_env_to_intl (msg->env, &tag, &err)) { mutt_error (_("Bad IDN in \"%s\": '%s'"), tag, err); FREE (&err); } if (option (OPTCRYPTOPPORTUNISTICENCRYPT)) crypt_opportunistic_encrypt (msg); } else { /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the attachment list could change if the user invokes ~v to edit the message with headers, in which we need to execute the code below to regenerate the index array */ mutt_builtin_editor (msg->content->filename, msg, cur); } mutt_update_encoding (msg->content); /* attachments may have been added */ if (idxlen && idx[idxlen - 1]->content->next) { for (i = 0; i < idxlen; i++) { FREE (&idx[i]->tree); FREE (&idx[i]); } idxlen = 0; idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); menu->data = idx; menu->max = idxlen; } menu->redraw = REDRAW_FULL; mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_ATTACH_KEY: if (!(WithCrypto & APPLICATION_PGP)) break; if (idxlen == idxmax) { safe_realloc (&idx, sizeof (ATTACHPTR *) * (idxmax += 5)); menu->data = idx; } idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR)); if ((idx[idxlen]->content = crypt_pgp_make_key_attachment(NULL)) != NULL) { update_idx (menu, idx, idxlen++); menu->redraw |= REDRAW_INDEX; } else FREE (&idx[idxlen]); menu->redraw |= REDRAW_STATUS; if (option(OPTNEEDREDRAW)) { menu->redraw = REDRAW_FULL; unset_option(OPTNEEDREDRAW); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_ATTACH_FILE: { char *prompt, **files; int error, numfiles; fname[0] = 0; prompt = _("Attach file"); numfiles = 0; files = NULL; if (_mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, 0, 1, &files, &numfiles) == -1 || *fname == '\0') break; if (idxlen + numfiles >= idxmax) { safe_realloc (&idx, sizeof (ATTACHPTR *) * (idxmax += 5 + numfiles)); menu->data = idx; } error = 0; if (numfiles > 1) mutt_message _("Attaching selected files..."); for (i = 0; i < numfiles; i++) { char *att = files[i]; idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR)); idx[idxlen]->unowned = 1; idx[idxlen]->content = mutt_make_file_attach (att); if (idx[idxlen]->content != NULL) update_idx (menu, idx, idxlen++); else { error = 1; mutt_error (_("Unable to attach %s!"), att); FREE (&idx[idxlen]); } } FREE (&files); if (!error) mutt_clear_error (); menu->redraw |= REDRAW_INDEX | REDRAW_STATUS; } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_ATTACH_MESSAGE: { char *prompt; HEADER *h; fname[0] = 0; prompt = _("Open mailbox to attach message from"); if (Context) { strfcpy (fname, NONULL (Context->path), sizeof (fname)); mutt_pretty_mailbox (fname, sizeof (fname)); } if (mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, 1) == -1 || !fname[0]) break; mutt_expand_path (fname, sizeof (fname)); #ifdef USE_IMAP if (!mx_is_imap (fname)) #endif #ifdef USE_POP if (!mx_is_pop (fname)) #endif /* check to make sure the file exists and is readable */ if (access (fname, R_OK) == -1) { mutt_perror (fname); break; } menu->redraw = REDRAW_FULL; ctx = mx_open_mailbox (fname, M_READONLY, NULL); if (ctx == NULL) { mutt_error (_("Unable to open mailbox %s"), fname); break; } if (!ctx->msgcount) { mx_close_mailbox (ctx, NULL); FREE (&ctx); mutt_error _("No messages in that folder."); break; } this = Context; /* remember current folder and sort methods*/ oldSort = Sort; oldSortAux = SortAux; Context = ctx; set_option(OPTATTACHMSG); mutt_message _("Tag the messages you want to attach!"); close = mutt_index_menu (); unset_option(OPTATTACHMSG); if (!Context) { /* go back to the folder we started from */ Context = this; /* Restore old $sort and $sort_aux */ Sort = oldSort; SortAux = oldSortAux; menu->redraw |= REDRAW_INDEX | REDRAW_STATUS; break; } if (idxlen + Context->tagged >= idxmax) { safe_realloc (&idx, sizeof (ATTACHPTR *) * (idxmax += 5 + Context->tagged)); menu->data = idx; } for (i = 0; i < Context->msgcount; i++) { h = Context->hdrs[i]; if (h->tagged) { idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR)); idx[idxlen]->content = mutt_make_message_attach (Context, h, 1); if (idx[idxlen]->content != NULL) update_idx (menu, idx, idxlen++); else { mutt_error _("Unable to attach!"); FREE (&idx[idxlen]); } } } menu->redraw |= REDRAW_FULL; if (close == OP_QUIT) mx_close_mailbox (Context, NULL); else mx_fastclose_mailbox (Context); FREE (&Context); /* go back to the folder we started from */ Context = this; /* Restore old $sort and $sort_aux */ Sort = oldSort; SortAux = oldSortAux; } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_DELETE: CHECK_COUNT; if (idx[menu->current]->unowned) idx[menu->current]->content->unlink = 0; if (delete_attachment (menu, &idxlen, menu->current) == -1) break; mutt_update_tree (idx, idxlen); if (idxlen) { if (menu->current > idxlen - 1) menu->current = idxlen - 1; } else menu->current = 0; if (menu->current == 0) msg->content = idx[0]->content; menu->redraw |= REDRAW_STATUS; mutt_message_hook (NULL, msg, M_SEND2HOOK); break; #define CURRENT idx[menu->current]->content case OP_COMPOSE_TOGGLE_RECODE: { CHECK_COUNT; if (!mutt_is_text_part (CURRENT)) { mutt_error (_("Recoding only affects text attachments.")); break; } CURRENT->noconv = !CURRENT->noconv; if (CURRENT->noconv) mutt_message (_("The current attachment won't be converted.")); else mutt_message (_("The current attachment will be converted.")); menu->redraw = REDRAW_CURRENT; mutt_message_hook (NULL, msg, M_SEND2HOOK); break; } #undef CURRENT case OP_COMPOSE_EDIT_DESCRIPTION: CHECK_COUNT; strfcpy (buf, idx[menu->current]->content->description ? idx[menu->current]->content->description : "", sizeof (buf)); /* header names should not be translated */ if (mutt_get_field ("Description: ", buf, sizeof (buf), 0) == 0) { mutt_str_replace (&idx[menu->current]->content->description, buf); menu->redraw = REDRAW_CURRENT; } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_UPDATE_ENCODING: CHECK_COUNT; if (menu->tagprefix) { BODY *top; for (top = msg->content; top; top = top->next) { if (top->tagged) mutt_update_encoding (top); } menu->redraw = REDRAW_FULL; } else { mutt_update_encoding(idx[menu->current]->content); menu->redraw = REDRAW_CURRENT | REDRAW_STATUS; } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_TOGGLE_DISPOSITION: /* toggle the content-disposition between inline/attachment */ idx[menu->current]->content->disposition = (idx[menu->current]->content->disposition == DISPINLINE) ? DISPATTACH : DISPINLINE; menu->redraw = REDRAW_CURRENT; break; case OP_EDIT_TYPE: CHECK_COUNT; { mutt_edit_content_type (NULL, idx[menu->current]->content, NULL); /* this may have been a change to text/something */ mutt_update_encoding (idx[menu->current]->content); menu->redraw = REDRAW_CURRENT; } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_ENCODING: CHECK_COUNT; strfcpy (buf, ENCODING (idx[menu->current]->content->encoding), sizeof (buf)); if (mutt_get_field ("Content-Transfer-Encoding: ", buf, sizeof (buf), 0) == 0 && buf[0]) { if ((i = mutt_check_encoding (buf)) != ENCOTHER && i != ENCUUENCODED) { idx[menu->current]->content->encoding = i; menu->redraw = REDRAW_CURRENT | REDRAW_STATUS; mutt_clear_error(); } else mutt_error _("Invalid encoding."); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_SEND_MESSAGE: /* Note: We don't invoke send2-hook here, since we want to leave * users an opportunity to change settings from the ":" prompt. */ if(check_attachments(idx, idxlen) != 0) { menu->redraw = REDRAW_FULL; break; } #ifdef MIXMASTER if (msg->chain && mix_check_message (msg) != 0) break; #endif if (!fccSet && *fcc) { if ((i = query_quadoption (OPT_COPY, _("Save a copy of this message?"))) == -1) break; else if (i == M_NO) *fcc = 0; } loop = 0; r = 0; break; case OP_COMPOSE_EDIT_FILE: CHECK_COUNT; mutt_edit_file (NONULL(Editor), idx[menu->current]->content->filename); mutt_update_encoding (idx[menu->current]->content); menu->redraw = REDRAW_CURRENT | REDRAW_STATUS; mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_TOGGLE_UNLINK: CHECK_COUNT; idx[menu->current]->content->unlink = !idx[menu->current]->content->unlink; #if 0 /* OPTRESOLVE is otherwise ignored on this menu. * Where's the bug? */ if (option (OPTRESOLVE) && menu->current + 1 < menu->max) menu->current++; # endif menu->redraw = REDRAW_INDEX; /* No send2hook since this doesn't change the message. */ break; case OP_COMPOSE_GET_ATTACHMENT: CHECK_COUNT; if(menu->tagprefix) { BODY *top; for(top = msg->content; top; top = top->next) { if(top->tagged) mutt_get_tmp_attachment(top); } menu->redraw = REDRAW_FULL; } else if (mutt_get_tmp_attachment(idx[menu->current]->content) == 0) menu->redraw = REDRAW_CURRENT; /* No send2hook since this doesn't change the message. */ break; case OP_COMPOSE_RENAME_FILE: CHECK_COUNT; strfcpy (fname, idx[menu->current]->content->filename, sizeof (fname)); mutt_pretty_mailbox (fname, sizeof (fname)); if (mutt_get_field (_("Rename to: "), fname, sizeof (fname), M_FILE) == 0 && fname[0]) { if (stat(idx[menu->current]->content->filename, &st) == -1) { /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */ mutt_error (_("Can't stat %s: %s"), fname, strerror (errno)); break; } mutt_expand_path (fname, sizeof (fname)); if(mutt_rename_file (idx[menu->current]->content->filename, fname)) break; mutt_str_replace (&idx[menu->current]->content->filename, fname); menu->redraw = REDRAW_CURRENT; if(idx[menu->current]->content->stamp >= st.st_mtime) mutt_stamp_attachment(idx[menu->current]->content); } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_NEW_MIME: { char type[STRING]; char *p; int itype; FILE *fp; CLEARLINE (LINES-1); fname[0] = 0; if (mutt_get_field (_("New file: "), fname, sizeof (fname), M_FILE) != 0 || !fname[0]) continue; mutt_expand_path (fname, sizeof (fname)); /* Call to lookup_mime_type () ? maybe later */ type[0] = 0; if (mutt_get_field ("Content-Type: ", type, sizeof (type), 0) != 0 || !type[0]) continue; if (!(p = strchr (type, '/'))) { mutt_error _("Content-Type is of the form base/sub"); continue; } *p++ = 0; if ((itype = mutt_check_mime_type (type)) == TYPEOTHER) { mutt_error (_("Unknown Content-Type %s"), type); continue; } if (idxlen == idxmax) { safe_realloc (&idx, sizeof (ATTACHPTR *) * (idxmax += 5)); menu->data = idx; } idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR)); /* Touch the file */ if (!(fp = safe_fopen (fname, "w"))) { mutt_error (_("Can't create file %s"), fname); FREE (&idx[idxlen]); continue; } safe_fclose (&fp); if ((idx[idxlen]->content = mutt_make_file_attach (fname)) == NULL) { mutt_error _("What we have here is a failure to make an attachment"); continue; } update_idx (menu, idx, idxlen++); idx[menu->current]->content->type = itype; mutt_str_replace (&idx[menu->current]->content->subtype, p); idx[menu->current]->content->unlink = 1; menu->redraw |= REDRAW_INDEX | REDRAW_STATUS; if (mutt_compose_attachment (idx[menu->current]->content)) { mutt_update_encoding (idx[menu->current]->content); menu->redraw = REDRAW_FULL; } } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_COMPOSE_EDIT_MIME: CHECK_COUNT; if (mutt_edit_attachment (idx[menu->current]->content)) { mutt_update_encoding (idx[menu->current]->content); menu->redraw = REDRAW_FULL; } mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_VIEW_ATTACH: case OP_DISPLAY_HEADERS: CHECK_COUNT; mutt_attach_display_loop (menu, op, NULL, NULL, NULL, &idx, &idxlen, NULL, 0); menu->redraw = REDRAW_FULL; /* no send2hook, since this doesn't modify the message */ break; case OP_SAVE: CHECK_COUNT; mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content, NULL, menu); MAYBE_REDRAW (menu->redraw); /* no send2hook, since this doesn't modify the message */ break; case OP_PRINT: CHECK_COUNT; mutt_print_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content); /* no send2hook, since this doesn't modify the message */ break; case OP_PIPE: case OP_FILTER: CHECK_COUNT; mutt_pipe_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content, op == OP_FILTER); if (op == OP_FILTER) /* cte might have changed */ menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT; menu->redraw |= REDRAW_STATUS; mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_EXIT: if ((i = query_quadoption (OPT_POSTPONE, _("Postpone this message?"))) == M_NO) { for (i = 0; i < idxlen; i++) if (idx[i]->unowned) idx[i]->content->unlink = 0; if (!(flags & M_COMPOSE_NOFREEHEADER)) { while (idxlen-- > 0) { /* avoid freeing other attachments */ idx[idxlen]->content->next = NULL; idx[idxlen]->content->parts = NULL; mutt_free_body (&idx[idxlen]->content); FREE (&idx[idxlen]->tree); FREE (&idx[idxlen]); } FREE (&idx); idxlen = 0; idxmax = 0; } r = -1; loop = 0; break; } else if (i == -1) break; /* abort */ /* fall through to postpone! */ case OP_COMPOSE_POSTPONE_MESSAGE: if(check_attachments(idx, idxlen) != 0) { menu->redraw = REDRAW_FULL; break; } loop = 0; r = 1; break; case OP_COMPOSE_ISPELL: endwin (); snprintf (buf, sizeof (buf), "%s -x %s", NONULL(Ispell), msg->content->filename); if (mutt_system (buf) == -1) mutt_error (_("Error running \"%s\"!"), buf); else { mutt_update_encoding (msg->content); menu->redraw |= REDRAW_STATUS; } break; case OP_COMPOSE_WRITE_MESSAGE: fname[0] = '\0'; if (Context) { strfcpy (fname, NONULL (Context->path), sizeof (fname)); mutt_pretty_mailbox (fname, sizeof (fname)); } if (idxlen) msg->content = idx[0]->content; if (mutt_enter_fname (_("Write message to mailbox"), fname, sizeof (fname), &menu->redraw, 1) != -1 && fname[0]) { mutt_message (_("Writing message to %s ..."), fname); mutt_expand_path (fname, sizeof (fname)); if (msg->content->next) msg->content = mutt_make_multipart (msg->content); if (mutt_write_fcc (fname, msg, NULL, 0, NULL) < 0) msg->content = mutt_remove_multipart (msg->content); else mutt_message _("Message written."); } break; case OP_COMPOSE_PGP_MENU: if (!(WithCrypto & APPLICATION_PGP)) break; if ((WithCrypto & APPLICATION_SMIME) && (msg->security & APPLICATION_SMIME)) { if (msg->security & (ENCRYPT | SIGN)) { if (mutt_yesorno (_("S/MIME already selected. Clear & continue ? "), M_YES) != M_YES) { mutt_clear_error (); break; } msg->security &= ~(ENCRYPT | SIGN); } msg->security &= ~APPLICATION_SMIME; msg->security |= APPLICATION_PGP; crypt_opportunistic_encrypt (msg); redraw_crypt_lines (msg); } msg->security = crypt_pgp_send_menu (msg, &menu->redraw); redraw_crypt_lines (msg); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; case OP_FORGET_PASSPHRASE: crypt_forget_passphrase (); break; case OP_COMPOSE_SMIME_MENU: if (!(WithCrypto & APPLICATION_SMIME)) break; if ((WithCrypto & APPLICATION_PGP) && (msg->security & APPLICATION_PGP)) { if (msg->security & (ENCRYPT | SIGN)) { if (mutt_yesorno (_("PGP already selected. Clear & continue ? "), M_YES) != M_YES) { mutt_clear_error (); break; } msg->security &= ~(ENCRYPT | SIGN); } msg->security &= ~APPLICATION_PGP; msg->security |= APPLICATION_SMIME; crypt_opportunistic_encrypt (msg); redraw_crypt_lines (msg); } msg->security = crypt_smime_send_menu(msg, &menu->redraw); redraw_crypt_lines (msg); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; #ifdef MIXMASTER case OP_COMPOSE_MIX: mix_make_chain (&msg->chain, &menu->redraw); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; #endif } /* Draw formatted compose status line */ if (menu->redraw & REDRAW_STATUS) { compose_status_line (buf, sizeof (buf), 0, menu, NONULL(ComposeFormat)); move(option (OPTSTATUSONTOP) ? 0 : LINES-2, 0); SETCOLOR (MT_COLOR_STATUS); mutt_paddstr (COLS, buf); NORMAL_COLOR; menu->redraw &= ~REDRAW_STATUS; } } mutt_menuDestroy (&menu); if (idxlen) { msg->content = idx[0]->content; for (i = 0; i < idxlen; i++) { idx[i]->content->aptr = NULL; FREE (&idx[i]->tree); FREE (&idx[i]); } } else msg->content = NULL; FREE (&idx); return (r); }
void ci_bounce_message (HEADER *h, int *redraw) { char prompt[SHORT_STRING]; char scratch[SHORT_STRING]; char buf[HUGE_STRING] = { 0 }; ADDRESS *adr = NULL; char *err = NULL; int rc; /* RfC 5322 mandates a From: header, so warn before bouncing * messages without one */ if (h) { if (!h->env->from) { mutt_error _("Warning: message contains no From: header"); mutt_sleep (2); } } else if (Context) { for (rc = 0; rc < Context->msgcount; rc++) { if (Context->hdrs[rc]->tagged && !Context->hdrs[rc]->env->from) { mutt_error _("Warning: message contains no From: header"); mutt_sleep (2); break; } } } if(h) strfcpy(prompt, _("Bounce message to: "), sizeof(prompt)); else strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt)); rc = mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS); if (option (OPTNEEDREDRAW)) { unset_option (OPTNEEDREDRAW); *redraw = REDRAW_FULL; } if (rc || !buf[0]) return; if (!(adr = mutt_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); if (mutt_addrlist_to_intl (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); FREE (&err); rfc822_free_address (&adr); return; } buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15 + 7 + 2) snprintf (scratch, sizeof (scratch), (h ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt), 0, COLS-extra_space, FMT_LEFT, 0, scratch, sizeof (scratch), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } else snprintf (prompt, sizeof (prompt), "%s?", scratch); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (h ? _("Message not bounced.") : _("Messages not bounced.")); return; } CLEARLINE (LINES - 1); rc = mutt_bounce_message (NULL, h, adr); rfc822_free_address (&adr); /* If no error, or background, display message. */ if ((rc == 0) || (rc == S_BKG)) mutt_message (h ? _("Message bounced.") : _("Messages bounced.")); }
void mutt_attach_bounce (FILE * fp, HEADER * hdr, ATTACHPTR ** idx, short idxlen, BODY * cur) { short i; char prompt[STRING]; char buf[HUGE_STRING]; char *err = NULL; ADDRESS *adr = NULL; int ret = 0; int p = 0; if (check_all_msg (idx, idxlen, cur, 1) == -1) return; /* one or more messages? */ p = (cur || count_tagged (idx, idxlen) == 1); if (p) strfcpy (prompt, _("Bounce message to: "), sizeof (prompt)); else strfcpy (prompt, _("Bounce tagged messages to: "), sizeof (prompt)); buf[0] = '\0'; if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) || buf[0] == '\0') return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); if (mutt_addrlist_to_idna (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); mem_free (&err); rfc822_free_address (&adr); return; } buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15+7+2) /* * See commands.c. */ snprintf (prompt, sizeof (prompt) - 4, (p ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt) - 4, 0, COLS - extra_space, 0, 0, prompt, sizeof (prompt), 0); str_cat (prompt, sizeof (prompt), "...?"); } else str_cat (prompt, sizeof (prompt), "?"); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (p ? _("Message not bounced.") : _("Messages not bounced.")); return; } CLEARLINE (LINES - 1); if (cur) ret = mutt_bounce_message (fp, cur->hdr, adr); else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) if (mutt_bounce_message (fp, idx[i]->content->hdr, adr)) ret = 1; } } if (!ret) mutt_message (p ? _("Message bounced.") : _("Messages bounced.")); else mutt_error (p ? _("Error bouncing message!") : _("Error bouncing messages!")); }
void mutt_clear_error (void) { Errorbuf[0] = 0; if (!option(OPTNOCURSES)) CLEARLINE (LINES-1); }
/* returns 0 if OK to proceed, -1 to abort, 1 to retry */ int mutt_save_confirm (const char *s, struct stat *st) { char tmp[_POSIX_PATH_MAX]; int ret = 0; int rc; int magic = 0; magic = mx_get_magic (s); #ifdef USE_POP if (magic == M_POP) { mutt_error _("Can't save message to POP mailbox."); return 1; } #endif #ifdef USE_NNTP if (magic == M_NNTP) { mutt_error _("Can't save message to newsserver."); return 0; } #endif if (magic > 0 && !mx_access (s, W_OK)) { if (option (OPTCONFIRMAPPEND) && (!TrashPath || (str_cmp (s, TrashPath) != 0))) { /* if we're appending to the trash, there's no point in asking */ snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s); if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO) ret = 1; else if (rc == -1) ret = -1; } } if (stat (s, st) != -1) { if (magic == -1) { mutt_error (_("%s is not a mailbox!"), s); return 1; } } else { #ifdef USE_IMAP if (magic != M_IMAP) #endif /* execute the block unconditionally if we don't use imap */ { st->st_mtime = 0; st->st_atime = 0; if (errno == ENOENT) { if (option (OPTCONFIRMCREATE)) { snprintf (tmp, sizeof (tmp), _("Create %s?"), s); if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO) ret = 1; else if (rc == -1) ret = -1; } } else { mutt_perror (s); return 1; } } } CLEARLINE (LINES - 1); return (ret); }
void mutt_attach_bounce (FILE * fp, struct header * hdr, ATTACHPTR ** idx, short idxlen, struct body * cur) { short i; char prompt[STRING]; char buf[HUGE_STRING]; struct address *adr = NULL; int ret = 0; int p = 0; if (check_all_msg (idx, idxlen, cur, 1) == -1) return; /* one or more messages? */ p = (cur || count_tagged (idx, idxlen) == 1); /* RfC 5322 mandates a From: header, so warn before bouncing * messages without one */ if (cur) { if (!cur->hdr->env->from) { mutt_error("Warning: message contains no From: header"); mutt_sleep(2); mutt_clear_error(); } } else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) { if (!idx[i]->content->hdr->env->from) { mutt_error("Warning: message contains no From: header"); mutt_sleep (2); mutt_clear_error (); break; } } } } if (p) strfcpy (prompt, ("Bounce message to: "), sizeof (prompt)); else strfcpy (prompt, ("Bounce tagged messages to: "), sizeof (prompt)); buf[0] = '\0'; if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) || buf[0] == '\0') return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15+7+2) /* * See commands.c. */ snprintf (prompt, sizeof (prompt) - 4, (p ? ("Bounce message to %s") : ("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt) - 4, 0, COLS-extra_space, FMT_LEFT, 0, prompt, sizeof (prompt), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } else safe_strcat (prompt, sizeof (prompt), "?"); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (p ? ("Message not bounced.") : ("Messages not bounced.")); return; } CLEARLINE (LINES - 1); if (cur) ret = mutt_bounce_message (fp, cur->hdr, adr); else { for (i = 0; i < idxlen; i++) { if (idx[i]->content->tagged) if (mutt_bounce_message (fp, idx[i]->content->hdr, adr)) ret = 1; } } if (!ret) mutt_message (p ? ("Message bounced.") : ("Messages bounced.")); else mutt_error (p ? ("Error bouncing message!") : ("Error bouncing messages!")); }
int mutt_menuLoop (MUTTMENU * menu) { int i = OP_NULL; FOREVER { if (option (OPTMENUCALLER)) { unset_option (OPTMENUCALLER); return OP_NULL; } mutt_curs_set (0); #ifdef USE_IMAP imap_keepalive (); #endif if (menu_redraw (menu) == OP_REDRAW) return OP_REDRAW; menu->oldcurrent = menu->current; if (option (OPTARROWCURSOR)) move (menu->current - menu->top + menu->offset, SW + 2); else if (option (OPTBRAILLEFRIENDLY)) move (menu->current - menu->top + menu->offset, SW); else move (menu->current - menu->top + menu->offset, COLS - 1); mutt_refresh (); /* try to catch dialog keys before ops */ if (menu->dialog && menu_dialog_dokey (menu, &i) == 0) return i; i = km_dokey (menu->menu); if (i == OP_TAG_PREFIX || i == OP_TAG_PREFIX_COND) { if (menu->tagged) { mvaddstr (LINES - 1, 0, "Tag-"); clrtoeol (); i = km_dokey (menu->menu); menu->tagprefix = 1; CLEARLINE (LINES - 1); } else if (i == OP_TAG_PREFIX) { mutt_error _("No tagged entries."); i = -1; } else { /* None tagged, OP_TAG_PREFIX_COND */ event_t tmp; while (UngetCount > 0) { tmp = mutt_getch (); if (tmp.op == OP_END_COND) break; } mutt_message _("Nothing to do."); i = -1; } } else if (menu->tagged && option (OPTAUTOTAG)) menu->tagprefix = 1; else menu->tagprefix = 0; mutt_curs_set (1); #if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM) if (SigWinch) { mutt_resize_screen (); menu->redraw = REDRAW_FULL; SigWinch = 0; clearok (stdscr, TRUE); /*force complete redraw */ } #endif if (i == -1) continue; if (!menu->dialog) mutt_clear_error (); /* Convert menubar movement to scrolling */ if (menu->dialog) i = menu_dialog_translate_op (i); switch (i) { case OP_NEXT_ENTRY: menu_next_entry (menu); break; case OP_PREV_ENTRY: menu_prev_entry (menu); break; case OP_HALF_DOWN: menu_half_down (menu); break; case OP_HALF_UP: menu_half_up (menu); break; case OP_NEXT_PAGE: menu_next_page (menu); break; case OP_PREV_PAGE: menu_prev_page (menu); break; case OP_NEXT_LINE: menu_next_line (menu); break; case OP_PREV_LINE: menu_prev_line (menu); break; case OP_FIRST_ENTRY: menu_first_entry (menu); break; case OP_LAST_ENTRY: menu_last_entry (menu); break; case OP_TOP_PAGE: menu_top_page (menu); break; case OP_MIDDLE_PAGE: menu_middle_page (menu); break; case OP_BOTTOM_PAGE: menu_bottom_page (menu); break; case OP_CURRENT_TOP: menu_current_top (menu); break; case OP_CURRENT_MIDDLE: menu_current_middle (menu); break; case OP_CURRENT_BOTTOM: menu_current_bottom (menu); break; case OP_SEARCH: case OP_SEARCH_REVERSE: case OP_SEARCH_NEXT: case OP_SEARCH_OPPOSITE: if (menu->search && !menu->dialog) { /* Searching dialogs won't work */ menu->oldcurrent = menu->current; if ((menu->current = menu_search (menu, i)) != -1) menu->redraw = REDRAW_MOTION; else menu->current = menu->oldcurrent; } else mutt_error _("Search is not implemented for this menu."); break; case OP_JUMP: if (menu->dialog) mutt_error (_("Jumping is not implemented for dialogs.")); else menu_jump (menu); break; case OP_ENTER_COMMAND: CurrentMenu = menu->menu; mutt_enter_command (); if (option (OPTFORCEREDRAWINDEX)) { menu->redraw = REDRAW_FULL; unset_option (OPTFORCEREDRAWINDEX); unset_option (OPTFORCEREDRAWPAGER); } break; case OP_TAG: if (menu->tag && !menu->dialog) { if (menu->tagprefix && !option (OPTAUTOTAG)) { for (i = 0; i < menu->max; i++) menu->tagged += menu->tag (menu, i, 0); menu->redraw = REDRAW_INDEX; } else if (menu->max) { int i = menu->tag (menu, menu->current, -1); menu->tagged += i; if (i && option (OPTRESOLVE) && menu->current < menu->max - 1) { menu->current++; menu->redraw = REDRAW_MOTION_RESYNCH; } else menu->redraw = REDRAW_CURRENT; } else mutt_error _("No entries."); } else mutt_error _("Tagging is not supported."); break; case OP_SHELL_ESCAPE: mutt_shell_escape (); MAYBE_REDRAW (menu->redraw); break; case OP_WHAT_KEY: mutt_what_key (); break; case OP_REBUILD_CACHE: mx_rebuild_cache (); break; case OP_REDRAW: clearok (stdscr, TRUE); menu->redraw = REDRAW_FULL; break; case OP_HELP: mutt_help (menu->menu); menu->redraw = REDRAW_FULL; break; case OP_NULL: km_error_key (menu->menu); break; case OP_END_COND: break; default: return (i); } } /* not reached */ }
void ci_bounce_message (HEADER *h, int *redraw) { char prompt[SHORT_STRING]; char scratch[SHORT_STRING]; char buf[HUGE_STRING] = { 0 }; ADDRESS *adr = NULL; char *err = NULL; int rc; if(h) strfcpy(prompt, _("Bounce message to: "), sizeof(prompt)); else strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt)); rc = mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS); if (option (OPTNEEDREDRAW)) { unset_option (OPTNEEDREDRAW); *redraw = REDRAW_FULL; } if (rc || !buf[0]) return; if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); return; } adr = mutt_expand_aliases (adr); if (mutt_addrlist_to_idna (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); FREE (&err); rfc822_free_address (&adr); return; } buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, 1); #define extra_space (15 + 7 + 2) snprintf (scratch, sizeof (scratch), (h ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt), 0, COLS-extra_space, FMT_LEFT, 0, scratch, sizeof (scratch), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } else snprintf (prompt, sizeof (prompt), "%s?", scratch); if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { rfc822_free_address (&adr); CLEARLINE (LINES - 1); mutt_message (h ? _("Message not bounced.") : _("Messages not bounced.")); return; } CLEARLINE (LINES - 1); rc = mutt_bounce_message (NULL, h, adr); rfc822_free_address (&adr); /* If no error, or background, display message. */ if ((rc == 0) || (rc == S_BKG)) mutt_message (h ? _("Message bounced.") : _("Messages bounced.")); }