📄 message.c
字号:
/* cleanup */ if (delete) { if (!h) for (n = 0; n < ctx->msgcount; n++) { if (ctx->hdrs[n]->tagged) { mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1); if (option (OPTDELETEUNTAG)) mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0); } } else { mutt_set_flag (ctx, h, M_DELETE, 1); if (option (OPTDELETEUNTAG)) mutt_set_flag (ctx, h, M_TAG, 0); } } if (cmd.data) FREE (&cmd.data); if (sync_cmd.data) FREE (&sync_cmd.data); FREE (&mx.mbox); return 0; fail: if (cmd.data) FREE (&cmd.data); if (sync_cmd.data) FREE (&sync_cmd.data); FREE (&mx.mbox); return -1;}static body_cache_t *msg_cache_open (IMAP_DATA *idata){ char *s; char *p = idata->mailbox; char mailbox[_POSIX_PATH_MAX]; size_t mlen = sizeof (mailbox); if (idata->bcache) return idata->bcache; mailbox[0] = '\0'; for (s = mailbox; p && *p && mlen; mlen--) { if (*p == idata->delim) { *s = '/'; /* simple way to avoid collisions with UIDs */ if (*(p + 1) >= '0' && *(p + 1) <= '9') { mlen--; if (mlen) *++s = '_'; } } else *s = *p; *p++; *s++; } *s = '\0'; return mutt_bcache_open (&idata->conn->account, mailbox);}static FILE* msg_cache_get (IMAP_DATA* idata, HEADER* h){ char id[_POSIX_PATH_MAX]; if (!idata || !h) return NULL; idata->bcache = msg_cache_open (idata); snprintf (id, sizeof (id), "%u-%u", idata->uid_validity, HEADER_DATA(h)->uid); return mutt_bcache_get (idata->bcache, id);}static FILE* msg_cache_put (IMAP_DATA* idata, HEADER* h){ char id[_POSIX_PATH_MAX]; if (!idata || !h) return NULL; idata->bcache = msg_cache_open (idata); snprintf (id, sizeof (id), "%u-%u", idata->uid_validity, HEADER_DATA(h)->uid); return mutt_bcache_put (idata->bcache, id);}int imap_cache_del (IMAP_DATA* idata, HEADER* h){ char id[_POSIX_PATH_MAX]; if (!idata || !h) return -1; idata->bcache = msg_cache_open (idata); snprintf (id, sizeof (id), "%u-%u", idata->uid_validity, HEADER_DATA(h)->uid); return mutt_bcache_del (idata->bcache, id);}/* imap_add_keywords: concatenate custom IMAP tags to list, if they * appear in the folder flags list. Why wouldn't they? */void imap_add_keywords (char* s, HEADER* h, LIST* mailbox_flags, size_t slen){ LIST *keywords; if (!mailbox_flags || !HEADER_DATA(h) || !HEADER_DATA(h)->keywords) return; keywords = HEADER_DATA(h)->keywords->next; while (keywords) { if (imap_has_flag (mailbox_flags, keywords->data)) { safe_strcat (s, slen, keywords->data); safe_strcat (s, slen, " "); } keywords = keywords->next; }}/* imap_free_header_data: free IMAP_HEADER structure */void imap_free_header_data (void** data){ /* this should be safe even if the list wasn't used */ mutt_free_list (&(((IMAP_HEADER_DATA*) *data)->keywords)); FREE (data); /* __FREE_CHECKED__ */}/* imap_set_flags: fill out the message header according to the flags from * the server. Expects a flags line of the form "FLAGS (flag flag ...)" */char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s){ CONTEXT* ctx = idata->ctx; IMAP_HEADER newh; IMAP_HEADER_DATA* hd; unsigned char readonly; memset (&newh, 0, sizeof (newh)); hd = h->data; newh.data = hd; dprint (2, (debugfile, "imap_fetch_message: parsing FLAGS\n")); if ((s = msg_parse_flags (&newh, s)) == NULL) return NULL; /* YAUH (yet another ugly hack): temporarily set context to * read-write even if it's read-only, so *server* updates of * flags can be processed by mutt_set_flag. ctx->changed must * be restored afterwards */ readonly = ctx->readonly; ctx->readonly = 0; mutt_set_flag (ctx, h, M_NEW, !(hd->read || hd->old)); mutt_set_flag (ctx, h, M_OLD, hd->old); mutt_set_flag (ctx, h, M_READ, hd->read); mutt_set_flag (ctx, h, M_DELETE, hd->deleted); mutt_set_flag (ctx, h, M_FLAG, hd->flagged); mutt_set_flag (ctx, h, M_REPLIED, hd->replied); /* this message is now definitively *not* changed (mutt_set_flag * marks things changed as a side-effect) */ h->changed = 0; ctx->changed &= ~readonly; ctx->readonly = readonly; return s;}/* msg_fetch_header: import IMAP FETCH response into an IMAP_HEADER. * Expects string beginning with * n FETCH. * Returns: * 0 on success * -1 if the string is not a fetch response * -2 if the string is a corrupt fetch response */static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp){ IMAP_DATA* idata; long bytes; int rc = -1; /* default now is that string isn't FETCH response*/ idata = (IMAP_DATA*) ctx->data; if (buf[0] != '*') return rc; /* skip to message number */ buf = imap_next_word (buf); h->sid = atoi (buf); /* find FETCH tag */ buf = imap_next_word (buf); if (ascii_strncasecmp ("FETCH", buf, 5)) return rc; rc = -2; /* we've got a FETCH response, for better or worse */ if (!(buf = strchr (buf, '('))) return rc; buf++; /* FIXME: current implementation - call msg_parse_fetch - if it returns -2, * read header lines and call it again. Silly. */ if ((rc = msg_parse_fetch (h, buf) != -2) || !fp) return rc; if (imap_get_literal_count (buf, &bytes) == 0) { imap_read_literal (fp, idata, bytes, NULL); /* we may have other fields of the FETCH _after_ the literal * (eg Domino puts FLAGS here). Nothing wrong with that, either. * This all has to go - we should accept literals and nonliterals * interchangeably at any time. */ if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE) return rc; if (msg_parse_fetch (h, idata->buf) == -1) return rc; } rc = 0; /* success */ /* subtract headers from message size - unfortunately only the subset of * headers we've requested. */ h->content_length -= bytes; return rc;}/* msg_parse_fetch: handle headers returned from header fetch */static int msg_parse_fetch (IMAP_HEADER *h, char *s){ char tmp[SHORT_STRING]; char *ptmp; if (!s) return -1; while (*s) { SKIPWS (s); if (ascii_strncasecmp ("FLAGS", s, 5) == 0) { if ((s = msg_parse_flags (h, s)) == NULL) return -1; } else if (ascii_strncasecmp ("UID", s, 3) == 0) { s += 3; SKIPWS (s); h->data->uid = (unsigned int) atoi (s); s = imap_next_word (s); } else if (ascii_strncasecmp ("INTERNALDATE", s, 12) == 0) { s += 12; SKIPWS (s); if (*s != '\"') { dprint (1, (debugfile, "msg_parse_fetch(): bogus INTERNALDATE entry: %s\n", s)); return -1; } s++; ptmp = tmp; while (*s && *s != '\"') *ptmp++ = *s++; if (*s != '\"') return -1; s++; /* skip past the trailing " */ *ptmp = 0; h->received = imap_parse_date (tmp); } else if (ascii_strncasecmp ("RFC822.SIZE", s, 11) == 0) { s += 11; SKIPWS (s); ptmp = tmp; while (isdigit ((unsigned char) *s)) *ptmp++ = *s++; *ptmp = 0; h->content_length = atoi (tmp); } else if (!ascii_strncasecmp ("BODY", s, 4) || !ascii_strncasecmp ("RFC822.HEADER", s, 13)) { /* handle above, in msg_fetch_header */ return -2; } else if (*s == ')') s++; /* end of request */ else if (*s) { /* got something i don't understand */ imap_error ("msg_parse_fetch", s); return -1; } } return 0;}/* msg_parse_flags: read a FLAGS token into an IMAP_HEADER */static char* msg_parse_flags (IMAP_HEADER* h, char* s){ IMAP_HEADER_DATA* hd = h->data; /* sanity-check string */ if (ascii_strncasecmp ("FLAGS", s, 5) != 0) { dprint (1, (debugfile, "msg_parse_flags: not a FLAGS response: %s\n", s)); return NULL; } s += 5; SKIPWS(s); if (*s != '(') { dprint (1, (debugfile, "msg_parse_flags: bogus FLAGS response: %s\n", s)); return NULL; } s++; mutt_free_list (&hd->keywords); hd->deleted = hd->flagged = hd->replied = hd->read = hd->old = 0; /* start parsing */ while (*s && *s != ')') { if (ascii_strncasecmp ("\\deleted", s, 8) == 0) { s += 8; hd->deleted = 1; } else if (ascii_strncasecmp ("\\flagged", s, 8) == 0) { s += 8; hd->flagged = 1; } else if (ascii_strncasecmp ("\\answered", s, 9) == 0) { s += 9; hd->replied = 1; } else if (ascii_strncasecmp ("\\seen", s, 5) == 0) { s += 5; hd->read = 1; } else if (ascii_strncasecmp ("\\recent", s, 7) == 0) s += 7; else if (ascii_strncasecmp ("old", s, 3) == 0) { s += 3; hd->old = 1; } else { /* store custom flags as well */ char ctmp; char* flag_word = s; if (!hd->keywords) hd->keywords = mutt_new_list (); while (*s && !ISSPACE (*s) && *s != ')') s++; ctmp = *s; *s = '\0'; mutt_add_list (hd->keywords, flag_word); *s = ctmp; } SKIPWS(s); } /* wrap up, or note bad flags response */ if (*s == ')') s++; else { dprint (1, (debugfile, "msg_parse_flags: Unterminated FLAGS response: %s\n", s)); return NULL; } return s;}static void flush_buffer(char *buf, size_t *len, CONNECTION *conn){ buf[*len] = '\0'; mutt_socket_write_n(conn, buf, *len); *len = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -