⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imap.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* sanity-check string */  if (ascii_strncasecmp ("FLAGS", s, 5) != 0)  {    dprint (1, (debugfile, "imap_get_flags: not a FLAGS response: %s\n",      s));    return NULL;  }  s += 5;  SKIPWS(s);  if (*s != '(')  {    dprint (1, (debugfile, "imap_get_flags: bogus FLAGS response: %s\n",      s));    return NULL;  }  /* create list, update caller's flags handle */  flags = mutt_new_list();  *hflags = flags;  while (*s && *s != ')')  {    s++;    SKIPWS(s);    flag_word = s;    while (*s && (*s != ')') && !ISSPACE (*s))      s++;    ctmp = *s;    *s = '\0';    if (*flag_word)      mutt_add_list (flags, flag_word);    *s = ctmp;  }  /* note bad flags response */  if (*s != ')')  {    dprint (1, (debugfile,      "imap_get_flags: Unterminated FLAGS response: %s\n", s));    mutt_free_list (hflags);    return NULL;  }  s++;  return s;}int imap_open_mailbox (CONTEXT* ctx){  CONNECTION *conn;  IMAP_DATA *idata;  IMAP_STATUS* status, sb;  char buf[LONG_STRING];  char bufout[LONG_STRING];  int count = 0;  IMAP_MBOX mx, pmx;  int rc;    if (imap_parse_path (ctx->path, &mx))  {    mutt_error (_("%s is an invalid IMAP path"), ctx->path);    return -1;  }  /* we require a connection which isn't currently in IMAP_SELECTED state */  if (!(idata = imap_conn_find (&(mx.account), M_IMAP_CONN_NOSELECT)))    goto fail_noidata;  if (idata->state < IMAP_AUTHENTICATED)    goto fail;  conn = idata->conn;  /* once again the context is new */  ctx->data = idata;  /* Clean up path and replace the one in the ctx */  imap_fix_path (idata, mx.mbox, buf, sizeof (buf));  FREE(&(idata->mailbox));  idata->mailbox = safe_strdup (buf);  imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox);  FREE (&(ctx->path));  ctx->path = safe_strdup (buf);  idata->ctx = ctx;  /* clear mailbox status */  idata->status = 0;  memset (idata->rights, 0, (RIGHTSMAX+7)/8);  idata->newMailCount = 0;  mutt_message (_("Selecting %s..."), idata->mailbox);  imap_munge_mbox_name (buf, sizeof(buf), idata->mailbox);    /* pipeline ACL test */  if (mutt_bit_isset (idata->capabilities, ACL))  {    snprintf (bufout, sizeof (bufout), "MYRIGHTS %s", buf);    imap_cmd_queue (idata, bufout);  }  /* assume we have all rights if ACL is unavailable */  else  {    mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);    mutt_bit_set (idata->rights, IMAP_ACL_READ);    mutt_bit_set (idata->rights, IMAP_ACL_SEEN);    mutt_bit_set (idata->rights, IMAP_ACL_WRITE);    mutt_bit_set (idata->rights, IMAP_ACL_INSERT);    mutt_bit_set (idata->rights, IMAP_ACL_POST);    mutt_bit_set (idata->rights, IMAP_ACL_CREATE);    mutt_bit_set (idata->rights, IMAP_ACL_DELETE);  }  /* pipeline the postponed count if possible */  pmx.mbox = NULL;  if (mx_is_imap (Postponed) && !imap_parse_path (Postponed, &pmx)      && mutt_account_match (&pmx.account, &mx.account))    imap_status (Postponed, 1);  FREE (&pmx.mbox);  snprintf (bufout, sizeof (bufout), "%s %s",    ctx->readonly ? "EXAMINE" : "SELECT", buf);  idata->state = IMAP_SELECTED;  imap_cmd_start (idata, bufout);  if (!(status = imap_mboxcache_get (idata, idata->mailbox)))  {    memset (&sb, 0, sizeof (IMAP_STATUS));    sb.name = idata->mailbox;    idata->mboxcache = mutt_add_list_n (idata->mboxcache, &sb, sizeof (IMAP_STATUS));    status = imap_mboxcache_get (idata, idata->mailbox);    status->name = safe_strdup (idata->mailbox);  }  do  {    char *pc;        if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)      break;    pc = idata->buf + 2;    /* Obtain list of available flags here, may be overridden by a     * PERMANENTFLAGS tag in the OK response */    if (ascii_strncasecmp ("FLAGS", pc, 5) == 0)    {      /* don't override PERMANENTFLAGS */      if (!idata->flags)      {	dprint (2, (debugfile, "Getting mailbox FLAGS\n"));	if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)	  goto fail;      }    }    /* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */    else if (ascii_strncasecmp ("OK [PERMANENTFLAGS", pc, 18) == 0)    {      dprint (2, (debugfile, "Getting mailbox PERMANENTFLAGS\n"));      /* safe to call on NULL */      mutt_free_list (&(idata->flags));      /* skip "OK [PERMANENT" so syntax is the same as FLAGS */      pc += 13;      if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)	goto fail;    }    /* save UIDVALIDITY for the header cache */    else if (ascii_strncasecmp ("OK [UIDVALIDITY", pc, 14) == 0)    {      dprint (2, (debugfile, "Getting mailbox UIDVALIDITY\n"));      pc += 3;      pc = imap_next_word (pc);      idata->uid_validity = strtol (pc, NULL, 10);      status->uidvalidity = idata->uid_validity;    }    else if (ascii_strncasecmp ("OK [UIDNEXT", pc, 11) == 0)    {      dprint (2, (debugfile, "Getting mailbox UIDNEXT\n"));      pc += 3;      pc = imap_next_word (pc);      idata->uidnext = strtol (pc, NULL, 10);      status->uidnext = idata->uidnext;    }    else    {      pc = imap_next_word (pc);      if (!ascii_strncasecmp ("EXISTS", pc, 6))      {	count = idata->newMailCount;	idata->newMailCount = 0;      }    }  }  while (rc == IMAP_CMD_CONTINUE);  if (rc == IMAP_CMD_NO)  {    char *s;    s = imap_next_word (idata->buf); /* skip seq */    s = imap_next_word (s); /* Skip response */    mutt_error ("%s", s);    mutt_sleep (2);    goto fail;  }  if (rc != IMAP_CMD_OK)    goto fail;  /* check for READ-ONLY notification */  if (!ascii_strncasecmp (imap_get_qualifier (idata->buf), "[READ-ONLY]", 11)  \  && !mutt_bit_isset (idata->capabilities, ACL))  {    dprint (2, (debugfile, "Mailbox is read-only.\n"));    ctx->readonly = 1;  }#ifdef DEBUG  /* dump the mailbox flags we've found */  if (debuglevel > 2)  {    if (!idata->flags)      dprint (3, (debugfile, "No folder flags found\n"));    else    {      LIST* t = idata->flags;      dprint (3, (debugfile, "Mailbox flags: "));      t = t->next;      while (t)      {        dprint (3, (debugfile, "[%s] ", t->data));        t = t->next;      }      dprint (3, (debugfile, "\n"));    }  }#endif  if (!(mutt_bit_isset(idata->rights, IMAP_ACL_DELETE) ||        mutt_bit_isset(idata->rights, IMAP_ACL_SEEN) ||        mutt_bit_isset(idata->rights, IMAP_ACL_WRITE) ||        mutt_bit_isset(idata->rights, IMAP_ACL_INSERT)))     ctx->readonly = 1;  ctx->hdrmax = count;  ctx->hdrs = safe_calloc (count, sizeof (HEADER *));  ctx->v2r = safe_calloc (count, sizeof (int));  ctx->msgcount = 0;  if (count && (imap_read_headers (idata, 0, count-1) < 0))  {    mutt_error _("Error opening mailbox");    mutt_sleep (1);    goto fail;  }  dprint (2, (debugfile, "imap_open_mailbox: msgcount is %d\n", ctx->msgcount));  FREE (&mx.mbox);  return 0; fail:  if (idata->state == IMAP_SELECTED)    idata->state = IMAP_AUTHENTICATED; fail_noidata:  FREE (&mx.mbox);  return -1;}int imap_open_mailbox_append (CONTEXT *ctx){  CONNECTION *conn;  IMAP_DATA *idata;  char buf[LONG_STRING];  char mailbox[LONG_STRING];  IMAP_MBOX mx;  if (imap_parse_path (ctx->path, &mx))    return -1;  /* in APPEND mode, we appear to hijack an existing IMAP connection -   * ctx is brand new and mostly empty */  if (!(idata = imap_conn_find (&(mx.account), 0)))  {    FREE (&mx.mbox);    return -1;  }  conn = idata->conn;  ctx->magic = M_IMAP;  ctx->data = idata;  imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox));  FREE (&mx.mbox);  /* really we should also check for W_OK */  if (!imap_access (ctx->path, F_OK))    return 0;  snprintf (buf, sizeof (buf), _("Create %s?"), mailbox);  if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1)    return -1;  if (imap_create_mailbox (idata, mailbox) < 0)    return -1;  return 0;}/* imap_logout: Gracefully log out of server. */void imap_logout (IMAP_DATA* idata){  /* we set status here to let imap_handle_untagged know we _expect_ to   * receive a bye response (so it doesn't freak out and close the conn) */  idata->status = IMAP_BYE;  imap_cmd_start (idata, "LOGOUT");  while (imap_cmd_step (idata) == IMAP_CMD_CONTINUE)    ;  FREE(& idata->buf);  mutt_bcache_close (&idata->bcache);  FREE(& idata);}/* imap_set_flag: append str to flags if we currently have permission *   according to aclbit */static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag,  const char *str, char *flags, size_t flsize){  if (mutt_bit_isset (idata->rights, aclbit))    if (flag && imap_has_flag (idata->flags, str))      safe_strcat (flags, flsize, str);}/* imap_has_flag: do a caseless comparison of the flag against a flag list,*   return 1 if found or flag list has '\*', 0 otherwise */int imap_has_flag (LIST* flag_list, const char* flag){  if (!flag_list)    return 0;    flag_list = flag_list->next;  while (flag_list)  {    if (!ascii_strncasecmp (flag_list->data, flag, strlen (flag_list->data)))      return 1;        if (!ascii_strncmp (flag_list->data, "\\*", strlen (flag_list->data)))      return 1;        flag_list = flag_list->next;  }    return 0;}/* imap_make_msg_set: make an IMAP4rev1 UID message set out of a set of *   headers, given a flag enum to filter on. * Params: idata: IMAP_DATA containing context containing header set *         buf: to write message set into *         buflen: length of buffer *         flag: enum of flag type on which to filter *         changed: include only changed messages in message set *         invert: invert sense of flag, eg M_READ matches unread messages * Returns: number of messages in message set (0 if no matches) */int imap_make_msg_set (IMAP_DATA* idata, BUFFER* buf, int flag, int changed,                       int invert){  HEADER** hdrs;	/* sorted local copy */  int count = 0;	/* number of messages in message set */  int match = 0;	/* whether current message matches flag condition */  unsigned int setstart = 0;	/* start of current message range */  int n;  short oldsort;	/* we clobber reverse, must restore it */  int started = 0;  if (Sort != SORT_ORDER)  {    hdrs = safe_calloc (idata->ctx->msgcount, sizeof (HEADER*));    memcpy (hdrs, idata->ctx->hdrs, idata->ctx->msgcount * sizeof (HEADER*));        oldsort = Sort;    Sort = SORT_ORDER;    qsort ((void*) hdrs, idata->ctx->msgcount, sizeof (HEADER*),      mutt_get_sort_func (SORT_ORDER));    Sort = oldsort;  }  else    hdrs = idata->ctx->hdrs;    for (n = 0; n < idata->ctx->msgcount; n++)  {    match = 0;    /* don't include pending expunged messages */    if (hdrs[n]->active)      switch (flag)      {        case M_DELETED:          if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)            match = invert ^ hdrs[n]->deleted;	  break;        case M_FLAG:          if (hdrs[n]->flagged != HEADER_DATA(hdrs[n])->flagged)            match = invert ^ hdrs[n]->flagged;	  break;        case M_OLD:          if (hdrs[n]->old != HEADER_DATA(hdrs[n])->old)            match = invert ^ hdrs[n]->old;	  break;        case M_READ:          if (hdrs[n]->read != HEADER_DATA(hdrs[n])->read)            match = invert ^ hdrs[n]->read;	  break;        case M_REPLIED:          if (hdrs[n]->replied != HEADER_DATA(hdrs[n])->replied)            match = invert ^ hdrs[n]->replied;	  break;        case M_TAG:	  if (hdrs[n]->tagged)	    match = 1;	  break;      }    if (match && (!changed || hdrs[n]->changed))    {      count++;      if (setstart == 0)      {        setstart = HEADER_DATA (hdrs[n])->uid;        if (started == 0)	{	  mutt_buffer_printf (buf, "%u", HEADER_DATA (hdrs[n])->uid);	  started = 1;	}        else	  mutt_buffer_printf (buf, ",%u", HEADER_DATA (hdrs[n])->uid);      }      /* tie up if the last message also matches */      else if (n == idata->ctx->msgcount-1)	mutt_buffer_printf (buf, ":%u", HEADER_DATA (hdrs[n])->uid);    }    /* this message is not expunged and doesn't match. End current set. */    else if (setstart && hdrs[n]->active)    {      if (HEADER_DATA (hdrs[n-1])->uid > setstart)	mutt_buffer_printf (buf, ":%u", HEADER_DATA (hdrs[n-1])->uid);      setstart = 0;    }  }  if (Sort != SORT_ORDER)    FREE (&hdrs);  return count;}/* returns 0 if mutt's flags match cached server flags */static int compare_flags (HEADER* h){  IMAP_HEADER_DATA* hd = (IMAP_HEADER_DATA*)h->data;  if (h->read != hd->read)    return 1;  if (h->old != hd->old)    return 1;  if (h->flagged != hd->flagged)    return 1;  if (h->replied != hd->replied)    return 1;  if (h->deleted != hd->deleted)    return 1;  return 0;}/* Update the IMAP server to reflect the flags a single message.  */int imap_sync_message (IMAP_DATA *idata, HEADER *hdr, BUFFER *cmd,		       int *err_continue){  char flags[LONG_STRING];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -