/* enter a mutt command */ void mutt_enter_command (void) { BUFFER err, token; char buffer[LONG_STRING]; int r; buffer[0] = 0; if (mutt_get_field (":", buffer, sizeof (buffer), M_COMMAND) != 0 || !buffer[0]) return; mutt_buffer_init (&err); err.dsize = STRING; err.data = safe_malloc(err.dsize); mutt_buffer_init (&token); r = mutt_parse_rc_line (buffer, &token, &err); FREE (&token.data); if (err.data[0]) { /* since errbuf could potentially contain printf() sequences in it, we must call mutt_error() in this fashion so that vsprintf() doesn't expect more arguments that we passed */ if (r == 0) mutt_message ("%s", err.data); else mutt_error ("%s", err.data); } FREE (&err.data); }
static int check_attachments(ATTACHPTR **idx, short idxlen) { int i, r; struct stat st; char pretty[_POSIX_PATH_MAX], msg[_POSIX_PATH_MAX + SHORT_STRING]; for (i = 0; i < idxlen; i++) { strfcpy(pretty, idx[i]->content->filename, sizeof(pretty)); if(stat(idx[i]->content->filename, &st) != 0) { mutt_pretty_mailbox(pretty, sizeof (pretty)); mutt_error(_("%s [#%d] no longer exists!"), pretty, i+1); return -1; } if(idx[i]->content->stamp < st.st_mtime) { mutt_pretty_mailbox(pretty, sizeof (pretty)); snprintf(msg, sizeof(msg), _("%s [#%d] modified. Update encoding?"), pretty, i+1); if((r = mutt_yesorno(msg, M_YES)) == M_YES) mutt_update_encoding(idx[i]->content); else if(r == -1) return -1; } } return 0; }
static int edit_address_list (int line, ADDRESS **addr) { char buf[HUGE_STRING] = ""; /* needs to be large for alias expansion */ char *err = NULL; mutt_addrlist_to_local (*addr); rfc822_write_address (buf, sizeof (buf), *addr, 0); if (mutt_get_field (Prompts[line - 1], buf, sizeof (buf), M_ALIAS) == 0) { rfc822_free_address (addr); *addr = mutt_parse_adrlist (*addr, buf); *addr = mutt_expand_aliases (*addr); } if (option (OPTNEEDREDRAW)) { unset_option (OPTNEEDREDRAW); return (REDRAW_FULL); } if (mutt_addrlist_to_intl (*addr, &err) != 0) { mutt_error (_("Warning: '%s' is a bad IDN."), err); mutt_refresh(); FREE (&err); } /* redraw the expanded list so the user can see the result */ buf[0] = 0; rfc822_write_address (buf, sizeof (buf), *addr, 1); move (line, HDR_XOFFSET+SidebarWidth); mutt_paddstr (W, buf); return 0; }
/** * mutt_socket_readchar - simple read buffering to speed things up * @param[in] conn Connection to a server * @param[out] c Character that was read * @retval 1 Success * @retval -1 Error */ int mutt_socket_readchar(struct Connection *conn, char *c) { if (conn->bufpos >= conn->available) { if (conn->fd >= 0) conn->available = conn->conn_read(conn, conn->inbuf, sizeof(conn->inbuf)); else { mutt_debug(LL_DEBUG1, "attempt to read from closed connection.\n"); return -1; } conn->bufpos = 0; if (conn->available == 0) { mutt_error(_("Connection to %s closed"), conn->account.host); } if (conn->available <= 0) { mutt_socket_close(conn); return -1; } } *c = conn->inbuf[conn->bufpos]; conn->bufpos++; return 1; }
/* imap_auth_login: Plain LOGIN support */ imap_auth_res_t imap_auth_login (IMAP_DATA* idata, const char* method) { char q_user[SHORT_STRING], q_pass[SHORT_STRING]; char buf[STRING]; int rc; if (bit_val(idata->capabilities, LOGINDISABLED)) { mutt_message("LOGIN disabled on this server."); return IMAP_AUTH_UNAVAIL; } if (mutt_account_getuser (&idata->conn->account)) return IMAP_AUTH_FAILURE; if (mutt_account_getpass (&idata->conn->account)) return IMAP_AUTH_FAILURE; mutt_message("Logging in..."); imap_quote_string (q_user, sizeof (q_user), idata->conn->account.user); imap_quote_string (q_pass, sizeof (q_pass), idata->conn->account.pass); snprintf (buf, sizeof (buf), "LOGIN %s %s", q_user, q_pass); rc = imap_exec (idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS); if (!rc) { mutt_clear_error(); /* clear "Logging in...". fixes #3524 */ return IMAP_AUTH_SUCCESS; } mutt_error("Login failed."); mutt_sleep (2); return IMAP_AUTH_FAILURE; }
static char *get_query_string(struct nm_ctxdata *data) { struct uri_tag *item; if (!data) return NULL; if (data->db_query) return data->db_query; for (item = data->query_items; item; item = item->next) { if (!item->value || !item->name) continue; if (strcmp(item->name, "limit") == 0) { if (mutt_atoi(item->value, &data->db_limit)) mutt_error (_("failed to parse notmuch limit: %s"), item->value); } else if (strcmp(item->name, "type") == 0) data->query_type = string_to_guery_type(item->value); else if (strcmp(item->name, "query") == 0) data->db_query = safe_strdup(item->value); } if (!data->query_type) data->query_type = string_to_guery_type(NULL); dprint(2, (debugfile, "nm: query '%s'\n", data->db_query)); return data->db_query; }
/** * mutt_alias_menu - Display a menu of Aliases * @param buf Buffer for expanded aliases * @param buflen Length of buffer * @param aliases Alias List */ void mutt_alias_menu(char *buf, size_t buflen, struct AliasList *aliases) { struct Alias *a = NULL, *last = NULL; struct Menu *menu = NULL; struct Alias **alias_table = NULL; int t = -1; int i; bool done = false; char helpstr[1024]; int omax; if (TAILQ_EMPTY(aliases)) { mutt_error(_("You have no aliases")); return; } menu = mutt_menu_new(MENU_ALIAS); menu->menu_make_entry = alias_make_entry; menu->menu_tag = alias_tag; menu->title = _("Aliases"); menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ALIAS, AliasHelp); mutt_menu_push_current(menu); new_aliases: omax = menu->max; /* count the number of aliases */ TAILQ_FOREACH_FROM(a, aliases, entries) { a->del = false; a->tagged = false; menu->max++; }
static int smtp_auth (CONNECTION* conn) { int r = SMTP_AUTH_UNAVAIL; if (SmtpAuthenticators && *SmtpAuthenticators) { char* methods = safe_strdup (SmtpAuthenticators); char* method; char* delim; for (method = methods; method; method = delim) { delim = strchr (method, ':'); if (delim) *delim++ = '\0'; if (! method[0]) continue; dprint (2, (debugfile, "smtp_authenticate: Trying method %s\n", method)); r = smtp_auth_sasl (conn, method); if (r == SMTP_AUTH_FAIL && delim) { mutt_error (_("%s authentication failed, trying next method"), method); mutt_sleep (1); } else if (r != SMTP_AUTH_UNAVAIL) break; } FREE (&methods); } else r = smtp_auth_sasl (conn, AuthMechs); if (r != SMTP_AUTH_SUCCESS) mutt_account_unsetpass (&conn->account); if (r == SMTP_AUTH_FAIL) { mutt_error (_("SASL authentication failed")); mutt_sleep (1); } else if (r == SMTP_AUTH_UNAVAIL) { mutt_error (_("No authenticators available")); mutt_sleep (1); } return r == SMTP_AUTH_SUCCESS ? 0 : -1; }
void mutt_perror (const char *s) { char *p = strerror (errno); dprint (1, (debugfile, "%s: %s (errno = %d)\n", s, p ? p : "unknown error", errno)); mutt_error ("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno); }
static QUERY *run_query (char *s, int quiet) { FILE *fp; QUERY *first = NULL; QUERY *cur = NULL; char cmd[_POSIX_PATH_MAX]; char *buf = NULL; size_t buflen; int dummy = 0; char msg[STRING]; char *p; pid_t thepid; mutt_expand_file_fmt (cmd, sizeof(cmd), QueryCmd, s); if ((thepid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0) { dprint (1, (debugfile, "unable to fork command: %s", cmd)); return 0; } if (!quiet) mutt_message _("Waiting for response..."); fgets (msg, sizeof (msg), fp); if ((p = strrchr (msg, '\n'))) *p = '\0'; while ((buf = mutt_read_line (buf, &buflen, fp, &dummy, 0)) != NULL) { if ((p = strtok(buf, "\t\n"))) { if (first == NULL) { first = (QUERY *) safe_calloc (1, sizeof (QUERY)); cur = first; } else { cur->next = (QUERY *) safe_calloc (1, sizeof (QUERY)); cur = cur->next; } cur->addr = rfc822_parse_adrlist (cur->addr, p); p = strtok(NULL, "\t\n"); if (p) { cur->name = safe_strdup (p); p = strtok(NULL, "\t\n"); if (p) cur->other = safe_strdup (p); } } } FREE (&buf); safe_fclose (&fp); if (mutt_wait_filter (thepid)) { dprint (1, (debugfile, "Error: %s\n", msg)); if (!quiet) mutt_error ("%s", msg); } else { if (!quiet) mutt_message ("%s", msg); } return first; }
/** * comp_mbox_sync - Implements MxOps::mbox_sync() * * Changes in NeoMutt only affect the tmp file. * Calling comp_mbox_sync() will commit them to the compressed file. */ static int comp_mbox_sync(struct Mailbox *m, int *index_hint) { if (!m || !m->compress_info) return -1; struct CompressInfo *ci = m->compress_info; if (!ci->cmd_close) { mutt_error(_("Can't sync a compressed file without a close-hook")); return -1; } const struct MxOps *ops = ci->child_ops; if (!ops) return -1; if (!lock_realpath(m, true)) { mutt_error(_("Unable to lock mailbox")); return -1; } int rc = comp_mbox_check(m, index_hint); if (rc != 0) goto sync_cleanup; rc = ops->mbox_sync(m, index_hint); if (rc != 0) goto sync_cleanup; rc = execute_command(m, ci->cmd_close, _("Compressing %s")); if (rc == 0) { rc = -1; goto sync_cleanup; } rc = 0; sync_cleanup: store_size(m); unlock_realpath(m); return rc; }
/* ssl_negotiate: After SSL state has been initialized, attempt to negotiate * SSL over the wire, including certificate checks. */ static int ssl_negotiate (CONNECTION *conn, sslsockdata* ssldata) { int err; const char* errmsg; #if OPENSSL_VERSION_NUMBER >= 0x00906000L /* This only exists in 0.9.6 and above. Without it we may get interrupted * reads or writes. Bummer. */ SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY); #endif if ((err = SSL_connect (ssldata->ssl)) != 1) { switch (SSL_get_error (ssldata->ssl, err)) { case SSL_ERROR_SYSCALL: errmsg = _("I/O error"); break; case SSL_ERROR_SSL: errmsg = ERR_error_string (ERR_get_error (), NULL); break; default: errmsg = _("unknown error"); } mutt_error (_("SSL failed: %s"), errmsg); mutt_sleep (1); return -1; } ssldata->cert = SSL_get_peer_certificate (ssldata->ssl); if (!ssldata->cert) { mutt_error (_("Unable to get certificate from peer")); mutt_sleep (1); return -1; } if (!ssl_check_certificate (conn, ssldata)) return -1; mutt_message (_("%s connection using %s (%s)"), SSL_get_version(ssldata->ssl), SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl)); mutt_sleep (0); return 0; }
static short check_msg (struct body * b, short err) { if (!mutt_is_message_type (b->type, b->subtype)) { if (err) mutt_error("You may only bounce message/rfc822 parts."); return -1; } return 0; }
static int check_certificate_by_digest (X509 *peercert) { unsigned char peermd[EVP_MAX_MD_SIZE]; unsigned int peermdlen; X509 *cert = NULL; int pass = 0; FILE *fp; /* expiration check */ if (option (OPTSSLVERIFYDATES) != M_NO) { if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) { dprint (2, (debugfile, "Server certificate is not yet valid\n")); mutt_error (_("Server certificate is not yet valid")); mutt_sleep (2); return 0; } if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) { dprint (2, (debugfile, "Server certificate has expired")); mutt_error (_("Server certificate has expired")); mutt_sleep (2); return 0; } } if ((fp = fopen (SslCertFile, "rt")) == NULL) return 0; if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen)) { safe_fclose (&fp); return 0; } while ((cert = READ_X509_KEY (fp, &cert)) != NULL) { pass = compare_certificates (cert, peercert, peermd, peermdlen) ? 0 : 1; if (pass) break; } X509_free (cert); safe_fclose (&fp); return pass; }
/* return 0 on success, -1 on failure */ int mutt_sync_compressed (CONTEXT * ctx) { char *cmd; int rc = 0; FILE *fp; COMPRESS_INFO *ci = (COMPRESS_INFO *) ctx->compressinfo; if (!ctx->quiet) mutt_message (_("Compressing %s..."), ctx->realpath); cmd = get_compression_cmd (ci->close, ctx); if (cmd == NULL) return (-1); if ((fp = fopen (ctx->realpath, "a")) == NULL) { mutt_perror (ctx->realpath); mem_free (&cmd); return (-1); } mutt_block_signals (); if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) { fclose (fp); mutt_unblock_signals (); mutt_error _("Unable to lock mailbox!"); store_size (ctx); mem_free (&cmd); return (-1); } debug_print (2, ("CompressCommand: '%s'\n", cmd)); endwin (); fflush (stdout); sprintf (echo_cmd, _("echo Compressing %s..."), ctx->realpath); mutt_system (echo_cmd); if (mutt_system (cmd)) { mutt_any_key_to_continue (NULL); mutt_error (_ ("%s: Error compressing mailbox! Original mailbox deleted, uncompressed one kept!\n"), ctx->path); rc = -1; } mbox_unlock_compressed (ctx, fp); mutt_unblock_signals (); fclose (fp); mem_free (&cmd); store_size (ctx); return (rc); }
void mutt_edit_file (const char *editor, const char *data) { char cmd[LONG_STRING]; endwin (); mutt_expand_file_fmt (cmd, sizeof (cmd), editor, data); if (mutt_system (cmd) == -1) mutt_error (_("Error running \"%s\"!"), cmd); keypad (stdscr, TRUE); clearok (stdscr, TRUE); }
int raw_socket_write (CONNECTION* conn, const char* buf, size_t count) { int rc; if ((rc = write (conn->fd, buf, count)) == -1) { mutt_error (_("Error talking to %s (%s)"), conn->account.host, strerror (errno)); mutt_sleep (2); } return rc; }
/* update POP mailbox - delete messages from server */ int pop_sync_mailbox(CONTEXT *ctx, int *index_hint) { int i, j, ret = 0; char buf[LONG_STRING]; POP_DATA *pop_data = (POP_DATA *)ctx->data; progress_t progress; pop_data->check_time = 0; FOREVER { if (pop_reconnect(ctx) < 0) return -1; mutt_progress_init(&progress, _("Marking messages deleted..."), M_PROGRESS_MSG, WriteInc, ctx->deleted); for (i = 0, j = 0, ret = 0; ret == 0 && i < ctx->msgcount; i++) { if (ctx->hdrs[i]->deleted && (ctx->hdrs[i]->refno != -1)) { j++; if (!ctx->quiet) mutt_progress_update(&progress, j, -1); snprintf(buf, sizeof(buf), "DELE %d\r\n", ctx->hdrs[i]->refno); if ((ret = pop_query(pop_data, buf, sizeof(buf))) == 0) { mutt_bcache_del(pop_data->bcache, ctx->hdrs[i]->data); } } } if (ret == 0) { strfcpy(buf, "QUIT\r\n", sizeof(buf)); ret = pop_query(pop_data, buf, sizeof(buf)); } if (ret == 0) { pop_data->clear_cache = 1; pop_clear_cache(pop_data); pop_data->status = POP_DISCONNECTED; return 0; } if (ret == -2) { mutt_error("%s", pop_data->err_msg); mutt_sleep(2); return -1; } } }
/** * imap_auth_oauth - Authenticate an IMAP connection using OAUTHBEARER * @param adata Imap Account data * @param method Name of this authentication method (UNUSED) * @retval num Result, e.g. #IMAP_AUTH_SUCCESS */ enum ImapAuthRes imap_auth_oauth(struct ImapAccountData *adata, const char *method) { char *ibuf = NULL; char *oauthbearer = NULL; int ilen; int rc; /* For now, we only support SASL_IR also and over TLS */ if (!(adata->capabilities & IMAP_CAP_AUTH_OAUTHBEARER) || !(adata->capabilities & IMAP_CAP_SASL_IR) || !adata->conn->ssf) { return IMAP_AUTH_UNAVAIL; } /* If they did not explicitly request or configure oauth then fail quietly */ if (!(method || (C_ImapOauthRefreshCommand && *C_ImapOauthRefreshCommand))) return IMAP_AUTH_UNAVAIL; mutt_message(_("Authenticating (OAUTHBEARER)...")); /* We get the access token from the imap_oauth_refresh_command */ oauthbearer = mutt_account_getoauthbearer(&adata->conn->account); if (!oauthbearer) return IMAP_AUTH_FAILURE; ilen = mutt_str_strlen(oauthbearer) + 30; ibuf = mutt_mem_malloc(ilen); snprintf(ibuf, ilen, "AUTHENTICATE OAUTHBEARER %s", oauthbearer); /* This doesn't really contain a password, but the token is good for * an hour, so suppress it anyways. */ rc = imap_exec(adata, ibuf, IMAP_CMD_PASS); FREE(&oauthbearer); FREE(&ibuf); if (rc != IMAP_EXEC_SUCCESS) { /* The error response was in SASL continuation, so continue the SASL * to cause a failure and exit SASL input. See RFC 7628 3.2.3 */ mutt_socket_send(adata->conn, "\001"); rc = imap_exec(adata, ibuf, IMAP_CMD_NO_FLAGS); } if (rc == IMAP_EXEC_SUCCESS) { mutt_clear_error(); return IMAP_AUTH_SUCCESS; } mutt_error(_("OAUTHBEARER authentication failed.")); return IMAP_AUTH_FAILURE; }
int raw_socket_read (CONNECTION* conn, char* buf, size_t len) { int rc; if ((rc = read (conn->fd, buf, len)) == -1) { mutt_error (_("Error talking to %s (%s)"), conn->account.host, strerror (errno)); mutt_sleep (2); } return rc; }
/* 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); }
static int menu_search (MUTTMENU * menu, int op) { int r; int searchDir; regex_t re; char buf[SHORT_STRING]; if (op != OP_SEARCH_NEXT && op != OP_SEARCH_OPPOSITE) { strfcpy (buf, menu->searchBuf ? menu->searchBuf : "", sizeof (buf)); if (mutt_get_field ((op == OP_SEARCH) ? _("Search for: ") : _("Reverse search for: "), buf, sizeof (buf), M_CLEAR) != 0 || !buf[0]) return (-1); str_replace (&menu->searchBuf, buf); menu->searchDir = (op == OP_SEARCH) ? M_SEARCH_DOWN : M_SEARCH_UP; } else { if (!menu->searchBuf) { mutt_error _("No search pattern."); return (-1); } } searchDir = (menu->searchDir == M_SEARCH_UP) ? -1 : 1; if (op == OP_SEARCH_OPPOSITE) searchDir = -searchDir; if ((r = REGCOMP (&re, menu->searchBuf, REG_NOSUB | mutt_which_case (menu->searchBuf))) != 0) { regerror (r, &re, buf, sizeof (buf)); regfree (&re); mutt_error ("%s", buf); return (-1); } r = menu->current + searchDir; while (r >= 0 && r < menu->max) { if (menu->search (menu, &re, r) == 0) { regfree (&re); return r; } r += searchDir; } regfree (&re); mutt_error _("Not found."); return (-1); }
static notmuch_database_t *do_database_open(const char *filename, int writable, int verbose) { notmuch_database_t *db = NULL; unsigned int ct = 0; notmuch_status_t st = NOTMUCH_STATUS_SUCCESS; dprint(1, (debugfile, "nm: db open '%s' %s (timeout %d)\n", filename, writable ? "[WRITE]" : "[READ]", NotmuchOpenTimeout)); do { #ifdef NOTMUCH_API_3 st = notmuch_database_open(filename, writable ? NOTMUCH_DATABASE_MODE_READ_WRITE : NOTMUCH_DATABASE_MODE_READ_ONLY, &db); #else db = notmuch_database_open(filename, writable ? NOTMUCH_DATABASE_MODE_READ_WRITE : NOTMUCH_DATABASE_MODE_READ_ONLY); #endif if (db || !NotmuchOpenTimeout || ct / 2 > NotmuchOpenTimeout) break; if (verbose && ct && ct % 2 == 0) mutt_error(_("Waiting for notmuch DB... (%d sec)"), ct / 2); usleep(500000); ct++; } while (1); if (verbose) { if (!db) mutt_error (_("Cannot open notmuch database: %s: %s"), filename, st ? notmuch_status_to_string(st) : _("unknown reason")); else if (ct > 1) mutt_clear_error(); } return db; }
/** * tls_set_priority - Set the priority of various protocols * @param data TLS socket data * @retval 0 Success * @retval -1 Error */ static int tls_set_priority(struct TlsSockData *data) { size_t nproto = 0; /* number of tls/ssl protocols */ if (C_SslUseTlsv12) protocol_priority[nproto++] = GNUTLS_TLS1_2; if (C_SslUseTlsv11) protocol_priority[nproto++] = GNUTLS_TLS1_1; if (C_SslUseTlsv1) protocol_priority[nproto++] = GNUTLS_TLS1; if (C_SslUseSslv3) protocol_priority[nproto++] = GNUTLS_SSL3; protocol_priority[nproto] = 0; if (nproto == 0) { mutt_error(_("All available protocols for TLS/SSL connection disabled")); return -1; } if (C_SslCiphers) { mutt_error( _("Explicit ciphersuite selection via $ssl_ciphers not supported")); } if (certerr & CERTERR_INSECUREALG) { row++; strfcpy(menu->dialog[row], _("Warning: Server certificate was signed using an insecure algorithm"), dialog_row_len); } /* We use default priorities (see gnutls documentation), * except for protocol version */ gnutls_set_default_priority(data->state); gnutls_protocol_set_priority(data->state, protocol_priority); return 0; }
/** * tls_socket_read - Read data from a TLS socket - Implements Connection::conn_read() */ static int tls_socket_read(struct Connection *conn, char *buf, size_t count) { struct TlsSockData *data = conn->sockdata; int rc; if (!data) { mutt_error(_("Error: no TLS socket open")); return -1; } do { rc = gnutls_record_recv(data->state, buf, count); } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)); if (rc < 0) { mutt_error("tls_socket_read (%s)", gnutls_strerror(rc)); return -1; } return rc; }
/** * mutt_edit_file - Let the user edit a file * @param editor User's editor config * @param file File to edit */ void mutt_edit_file(const char *editor, const char *file) { char cmd[STR_COMMAND]; mutt_endwin(); mutt_file_expand_fmt_quote(cmd, sizeof(cmd), editor, file); if (mutt_system(cmd) != 0) { mutt_error(_("Error running \"%s\""), cmd); } /* the terminal may have been resized while the editor owned it */ mutt_resize_screen(); keypad(stdscr, true); clearok(stdscr, true); }
static int string_to_guery_type(const char *str) { if (!str) str = NotmuchQueryType; /* user's default */ if (!str) return NM_QUERY_TYPE_MESGS; /* hardcoded default */ if (strcmp(str, "threads") == 0) return NM_QUERY_TYPE_THREADS; else if (strcmp(str, "messages") == 0) return NM_QUERY_TYPE_MESGS; mutt_error (_("failed to parse notmuch query type: %s"), str); return NM_QUERY_TYPE_MESGS; }
/* * rfc1524_mailcap_lookup attempts to find the given type in the * list of mailcap files. On success, this returns the entry information * in *entry, and returns 1. On failure (not found), returns 0. * If entry == NULL just return 1 if the given type is found. */ int rfc1524_mailcap_lookup (BODY *a, char *type, rfc1524_entry *entry, int opt) { char path[_POSIX_PATH_MAX]; int x; int found = FALSE; char *curr = MailcapPath; /* rfc1524 specifies that a path of mailcap files should be searched. * joy. They say * $HOME/.mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap, etc * and overridden by the MAILCAPS environment variable, and, just to be nice, * we'll make it specifiable in .muttrc */ if (!curr || !*curr) { mutt_error _("No mailcap path specified"); return 0; } mutt_check_lookup_list (a, type, SHORT_STRING); while (!found && *curr) { x = 0; while (*curr && *curr != ':' && x < sizeof (path) - 1) { path[x++] = *curr; curr++; } if (*curr) curr++; if (!x) continue; path[x] = '\0'; mutt_expand_path (path, sizeof (path)); dprint(2,(debugfile,"Checking mailcap file: %s\n",path)); found = rfc1524_mailcap_parse (a, path, type, entry, opt); } if (entry && !found) mutt_error (_("mailcap entry for type %s not found"), type); return found; }
void mutt_account_hook (const char* url) { /* parsing commands with URLs in an account hook can cause a recursive * call. We just skip processing if this occurs. Typically such commands * belong in a folder-hook -- perhaps we should warn the user. */ static int inhook = 0; HOOK* hook; BUFFER token; BUFFER err; if (inhook) return; mutt_buffer_init (&err); err.dsize = STRING; err.data = safe_malloc (err.dsize); mutt_buffer_init (&token); for (hook = Hooks; hook; hook = hook->next) { if (! (hook->command && (hook->type & M_ACCOUNTHOOK))) continue; if ((regexec (hook->rx.rx, url, 0, NULL, 0) == 0) ^ hook->rx.not) { inhook = 1; if (mutt_parse_rc_line (hook->command, &token, &err) == -1) { FREE (&token.data); mutt_error ("%s", err.data); FREE (&err.data); mutt_sleep (1); inhook = 0; return; } inhook = 0; } } FREE (&token.data); FREE (&err.data); }
/* reconnect and verify idnexes if connection was lost */ int pop_reconnect (CONTEXT *ctx) { int ret; POP_DATA *pop_data = (POP_DATA *)ctx->data; progress_t progressbar; if (pop_data->status == POP_CONNECTED) return 0; if (pop_data->status == POP_BYE) return -1; FOREVER { mutt_socket_close (pop_data->conn); ret = pop_open_connection (pop_data); if (ret == 0) { int i; mutt_progress_init (&progressbar, _("Verifying message indexes..."), M_PROGRESS_SIZE, NetInc, 0); for (i = 0; i < ctx->msgcount; i++) ctx->hdrs[i]->refno = -1; ret = pop_fetch_data (pop_data, "UIDL\r\n", &progressbar, check_uidl, ctx); if (ret == -2) { mutt_error ("%s", pop_data->err_msg); mutt_sleep (2); } } if (ret == 0) return 0; pop_logout (ctx); if (ret < -1) return -1; if (query_quadoption (OPT_POPRECONNECT, _("Connection lost. Reconnect to POP server?")) != M_YES) return -1; } }