📄 command.c
字号:
/* server shut down our connection */ s += 3; SKIPWS (s); mutt_error ("%s", s); mutt_sleep (2); cmd_handle_fatal (idata); return -1; } else if (option (OPTIMAPSERVERNOISE) && (ascii_strncasecmp ("NO", s, 2) == 0)) { dprint (2, (debugfile, "Handling untagged NO\n")); /* Display the warning message from the server */ mutt_error ("%s", s+3); mutt_sleep (2); } return 0;}/* cmd_parse_capabilities: set capability bits according to CAPABILITY * response */static void cmd_parse_capability (IMAP_DATA* idata, char* s){ int x; char* bracket; dprint (2, (debugfile, "Handling CAPABILITY\n")); s = imap_next_word (s); if ((bracket = strchr (s, ']'))) *bracket = '\0'; FREE(&idata->capstr); idata->capstr = safe_strdup (s); memset (idata->capabilities, 0, sizeof (idata->capabilities)); while (*s) { for (x = 0; x < CAPMAX; x++) if (imap_wordcasecmp(Capabilities[x], s) == 0) { mutt_bit_set (idata->capabilities, x); break; } s = imap_next_word (s); }}/* cmd_parse_expunge: mark headers with new sequence ID and mark idata to * be reopened at our earliest convenience */static void cmd_parse_expunge (IMAP_DATA* idata, const char* s){ int expno, cur; HEADER* h; dprint (2, (debugfile, "Handling EXPUNGE\n")); expno = atoi (s); /* walk headers, zero seqno of expunged message, decrement seqno of those * above. Possibly we could avoid walking the whole list by resorting * and guessing a good starting point, but I'm guessing the resort would * nullify the gains */ for (cur = 0; cur < idata->ctx->msgcount; cur++) { h = idata->ctx->hdrs[cur]; if (h->index+1 == expno) h->index = -1; else if (h->index+1 > expno) h->index--; } idata->reopen |= IMAP_EXPUNGE_PENDING;}/* cmd_parse_fetch: Load fetch response into IMAP_DATA. Currently only * handles unanticipated FETCH responses, and only FLAGS data. We get * these if another client has changed flags for a mailbox we've selected. * Of course, a lot of code here duplicates code in message.c. */static void cmd_parse_fetch (IMAP_DATA* idata, char* s){ int msgno, cur; HEADER* h = NULL; dprint (2, (debugfile, "Handling FETCH\n")); msgno = atoi (s); if (msgno <= idata->ctx->msgcount) /* see cmd_parse_expunge */ for (cur = 0; cur < idata->ctx->msgcount; cur++) { h = idata->ctx->hdrs[cur]; if (h->active && h->index+1 == msgno) { dprint (2, (debugfile, "Message UID %d updated\n", HEADER_DATA(h)->uid)); break; } h = NULL; } if (!h) { dprint (1, (debugfile, "FETCH response ignored for this message\n")); return; } /* skip FETCH */ s = imap_next_word (s); s = imap_next_word (s); if (*s != '(') { dprint (1, (debugfile, "Malformed FETCH response")); return; } s++; if (ascii_strncasecmp ("FLAGS", s, 5) != 0) { dprint (2, (debugfile, "Only handle FLAGS updates\n")); return; } /* If server flags could conflict with mutt's flags, reopen the mailbox. */ if (h->changed) idata->reopen |= IMAP_EXPUNGE_PENDING; else { imap_set_flags (idata, h, s); idata->check_status = IMAP_FLAGS_PENDING; }}static void cmd_parse_list (IMAP_DATA* idata, char* s){ IMAP_LIST* list; IMAP_LIST lb; char delimbuf[5]; /* worst case: "\\"\0 */ if (idata->cmddata) list = (IMAP_LIST*)idata->cmddata; else list = &lb; memset (list, 0, sizeof (IMAP_LIST)); /* flags */ s = imap_next_word (s); if (*s != '(') { dprint (1, (debugfile, "Bad LIST response\n")); return; } s++; while (*s) { if (!ascii_strncasecmp (s, "\\NoSelect", 9)) list->noselect = 1; else if (!ascii_strncasecmp (s, "\\NoInferiors", 12)) list->noinferiors = 1; /* See draft-gahrns-imap-child-mailbox-?? */ else if (!ascii_strncasecmp (s, "\\HasNoChildren", 14)) list->noinferiors = 1; s = imap_next_word (s); if (*(s - 2) == ')') break; } /* Delimiter */ if (ascii_strncasecmp (s, "NIL", 3)) { delimbuf[0] = '\0'; safe_strcat (delimbuf, 5, s); imap_unquote_string (delimbuf); list->delim = delimbuf[0]; } /* Name */ s = imap_next_word (s); imap_unmunge_mbox_name (s); list->name = s; if (list->name[0] == '\0') { idata->delim = list->delim; dprint (2, (debugfile, "Root delimiter: %c\n", idata->delim)); }}static void cmd_parse_lsub (IMAP_DATA* idata, char* s){ char buf[STRING]; char errstr[STRING]; BUFFER err, token; ciss_url_t url; IMAP_LIST list; if (idata->cmddata) { /* caller will handle response itself */ cmd_parse_list (idata, s); return; } if (!option (OPTIMAPCHECKSUBSCRIBED)) return; idata->cmddata = &list; cmd_parse_list (idata, s); idata->cmddata = NULL; if (!list.name) return; dprint (2, (debugfile, "Subscribing to %s\n", list.name)); strfcpy (buf, "mailboxes \"", sizeof (buf)); mutt_account_tourl (&idata->conn->account, &url); url.path = list.name; if (!mutt_strcmp (url.user, ImapUser)) url.user = NULL; url_ciss_tostring (&url, buf + 11, sizeof (buf) - 10, 0); safe_strcat (buf, sizeof (buf), "\""); memset (&token, 0, sizeof (token)); err.data = errstr; err.dsize = sizeof (errstr); if (mutt_parse_rc_line (buf, &token, &err)) dprint (1, (debugfile, "Error adding subscribed mailbox: %s\n", errstr)); FREE (&token.data);}/* cmd_parse_myrights: set rights bits according to MYRIGHTS response */static void cmd_parse_myrights (IMAP_DATA* idata, const char* s){ dprint (2, (debugfile, "Handling MYRIGHTS\n")); s = imap_next_word ((char*)s); s = imap_next_word ((char*)s); /* zero out current rights set */ memset (idata->rights, 0, sizeof (idata->rights)); while (*s && !isspace((unsigned char) *s)) { switch (*s) { case 'l': mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP); break; case 'r': mutt_bit_set (idata->rights, IMAP_ACL_READ); break; case 's': mutt_bit_set (idata->rights, IMAP_ACL_SEEN); break; case 'w': mutt_bit_set (idata->rights, IMAP_ACL_WRITE); break; case 'i': mutt_bit_set (idata->rights, IMAP_ACL_INSERT); break; case 'p': mutt_bit_set (idata->rights, IMAP_ACL_POST); break; case 'c': mutt_bit_set (idata->rights, IMAP_ACL_CREATE); break; case 'd': mutt_bit_set (idata->rights, IMAP_ACL_DELETE); break; case 'a': mutt_bit_set (idata->rights, IMAP_ACL_ADMIN); break; } s++; }}/* This should be optimised (eg with a tree or hash) */static int uid2msgno (IMAP_DATA* idata, unsigned int uid){ int i; for (i = 0; i < idata->ctx->msgcount; i++) { HEADER* h = idata->ctx->hdrs[i]; if (HEADER_DATA(h)->uid == uid) return i; } return -1;}/* cmd_parse_search: store SEARCH response for later use */static void cmd_parse_search (IMAP_DATA* idata, const char* s){ unsigned int uid; int msgno; dprint (2, (debugfile, "Handling SEARCH\n")); while ((s = imap_next_word ((char*)s)) && *s != '\0') { uid = atoi (s); msgno = uid2msgno (idata, uid); if (msgno >= 0) idata->ctx->hdrs[uid2msgno (idata, uid)]->matched = 1; }}/* first cut: just do buffy update. Later we may wish to cache all * mailbox information, even that not desired by buffy */static void cmd_parse_status (IMAP_DATA* idata, char* s){ char* mailbox; char* value; BUFFY* inc; IMAP_MBOX mx; int count; IMAP_STATUS *status, sb; int olduv, oldun; mailbox = imap_next_word (s); s = imap_next_word (mailbox); *(s - 1) = '\0'; imap_unmunge_mbox_name (mailbox); if (!(status = imap_mboxcache_get (idata, mailbox))) { /* ugly interface - why should I look up what I just added? */ memset (&sb, 0, sizeof (IMAP_STATUS)); sb.name = mailbox; idata->mboxcache = mutt_add_list_n (idata->mboxcache, &sb, sizeof (IMAP_STATUS)); status = imap_mboxcache_get (idata, mailbox); status->name = safe_strdup (mailbox); } olduv = status->uidvalidity; oldun = status->uidnext; if (*s++ != '(') { dprint (1, (debugfile, "Error parsing STATUS\n")); return; } while (*s && *s != ')') { value = imap_next_word (s); count = strtol (value, &value, 10); if (!ascii_strncmp ("MESSAGES", s, 8)) status->messages = count; else if (!ascii_strncmp ("RECENT", s, 6)) status->recent = count; else if (!ascii_strncmp ("UIDNEXT", s, 7)) status->uidnext = count; else if (!ascii_strncmp ("UIDVALIDITY", s, 11)) status->uidvalidity = count; else if (!ascii_strncmp ("UNSEEN", s, 6)) status->unseen = count; s = value; if (*s && *s != ')') s = imap_next_word (s); } dprint (2, (debugfile, "%s (UIDVALIDITY: %d, UIDNEXT: %d) %d messages, %d recent, %d unseen\n", status->name, status->uidvalidity, status->uidnext, status->messages, status->recent, status->unseen)); /* caller is prepared to handle the result herself */ if (idata->cmddata) { memcpy (idata->cmddata, status, sizeof (IMAP_STATUS)); return; } dprint (2, (debugfile, "Running default STATUS handler\n")); /* should perhaps move this code back to imap_buffy_check */ for (inc = Incoming; inc; inc = inc->next) { if (inc->magic != M_IMAP) continue; if (imap_parse_path (inc->path, &mx) < 0) { dprint (1, (debugfile, "Error parsing mailbox %s, skipping\n", inc->path)); continue; } /* dprint (2, (debugfile, "Buffy entry: [%s] mbox: [%s]\n", inc->path, NONULL(mx.mbox))); */ if (mutt_account_match (&idata->conn->account, &mx.account)) { if (mx.mbox) { value = safe_strdup (mx.mbox); imap_fix_path (idata, mx.mbox, value, mutt_strlen (value) + 1); FREE (&mx.mbox); } else value = safe_strdup ("INBOX"); if (value && !imap_mxcmp (mailbox, value)) { dprint (2, (debugfile, "Found %s in buffy list (OV: %d ON: %d U: %d)\n", mailbox, olduv, oldun, status->unseen)); if (olduv && olduv == status->uidvalidity) { if (oldun < status->uidnext) { inc->new = status->unseen; } } else inc->new = status->unseen; /* forced back to keep detecting new mail until the mailbox is opened */ status->uidnext = oldun; FREE (&value); return; } FREE (&value); } FREE (&mx.mbox); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -