Exemple #1
0
Variant f_imap_search(const Resource& imap_stream, const String& criteria,
                      int64_t options /* = 0 */,
                      const String& charset /* = "" */) {
  ImapStream *obj = imap_stream.getTyped<ImapStream>();

  char *search_criteria = (char*)criteria.data();
  IMAPG(messages) = IMAPG(messages_tail) = NIL;

  SEARCHPGM *pgm = mail_criteria(search_criteria);

  mail_search_full(obj->m_stream,
                   (charset.empty() ? NIL : (char*)charset.data()),
                   pgm,
                   options);

  if (pgm && !(options & SE_FREE)) {
    mail_free_searchpgm(&pgm);
  }

  if (IMAPG(messages) == NIL) {
    return false;
  }

  Array ret(Array::Create());

  MESSAGELIST *cur = IMAPG(messages);
  while (cur != NIL) {
    ret.append((int64_t)cur->msgid);
    cur = cur->next;
  }
  mail_free_messagelist(&IMAPG(messages), &IMAPG(messages_tail));
  return ret;
}
  std::vector<long>
  ImapClient::search(const std::string& aHost, 
                     const std::string& aUsername, 
                     const std::string& aPassword, 
                     const std::string& aMailbox, 
                     const std::string& aCriteria, 
                     bool aUid) {
    
#include "linkage.c"
    
    /* IMPORTANT: make sure that the vector of found sequence numbers is empty! */
    theFoundSequenceNumbers.clear();
    
    MAILSTREAM* lSource = getMailStream(aHost, aUsername, aPassword, aMailbox, true);
    checkMailStream(lSource);
    mail_ping(lSource);
    
    
    /* First, tokenize the criteria so that we can work on it */
    std::stringstream lToTokenize(aCriteria);
    std::string lBuffer;
    std::vector<std::string> lTokens;
    
    SEARCHPGM * lSearchProgram;
    while(lToTokenize >> lBuffer) {
      lTokens.push_back(lBuffer);
    }
    lSearchProgram = search_criteria(lTokens);
    
    mail_search_full(lSource, NIL,  lSearchProgram, (aUid ? SE_UID : NIL) | SE_NOPREFETCH); 
    /* clean up, don't leave a mess */
    mail_free_searchpgm(&lSearchProgram); 
    return theFoundSequenceNumbers;
  }
SEARCHPGM *prune_criteria (char *criteria)
{
  SEARCHPGM *pgm = NIL;
  char *criterion,*r,tmp[MAILTMPLEN];
  int f;
  if (criteria) {		/* only if criteria defined */
				/* make writeable copy of criteria */
    criteria = cpystr (criteria);
				/* for each criterion */
    for (pgm = mail_newsearchpgm (), criterion = strtok_r (criteria," ",&r);
	 criterion; (criterion = strtok_r (NIL," ",&r))) {
      f = NIL;			/* init then scan the criterion */
      switch (*ucase (criterion)) {
      case 'A':			/* possible ALL, ANSWERED */
	if (!strcmp (criterion+1,"LL")) f = T;
	else if (!strcmp (criterion+1,"NSWERED")) f = pgm->answered = T;
	break;
      case 'B':			/* possible BCC, BEFORE, BODY */
	if (!strcmp (criterion+1,"CC"))
	  f = mail_criteria_string (&pgm->bcc,&r);
	else if (!strcmp (criterion+1,"EFORE"))
	  f = mail_criteria_date (&pgm->before,&r);
	else if (!strcmp (criterion+1,"ODY"))
	  f = mail_criteria_string (&pgm->body,&r);
	break;
      case 'C':			/* possible CC */
	if (!strcmp (criterion+1,"C")) f = mail_criteria_string (&pgm->cc,&r);
	break;
      case 'D':			/* possible DELETED, DRAFT */
	if (!strcmp (criterion+1,"ELETED")) f = pgm->deleted = T;
	else if (!strcmp (criterion+1,"RAFT")) f = pgm->draft = T;
	break;
      case 'F':			/* possible FLAGGED, FROM */
	if (!strcmp (criterion+1,"LAGGED")) f = pgm->flagged = T;
	else if (!strcmp (criterion+1,"ROM"))
	  f = mail_criteria_string (&pgm->from,&r);
	break;
      case 'K':			/* possible KEYWORD */
	if (!strcmp (criterion+1,"EYWORD"))
	  f = mail_criteria_string (&pgm->keyword,&r);
	break;
      case 'L':			/* possible LARGER */
	if (!strcmp (criterion+1,"ARGER"))
	  f = prune_criteria_number (&pgm->larger,&r);

      case 'N':			/* possible NEW */
	if (!strcmp (criterion+1,"EW")) f = pgm->recent = pgm->unseen = T;
	break;
      case 'O':			/* possible OLD, ON */
	if (!strcmp (criterion+1,"LD")) f = pgm->old = T;
	else if (!strcmp (criterion+1,"N"))
	  f = mail_criteria_date (&pgm->on,&r);
	break;
      case 'R':			/* possible RECENT */
	if (!strcmp (criterion+1,"ECENT")) f = pgm->recent = T;
	break;
      case 'S':			/* possible SEEN, SENT*, SINCE, SMALLER,
				   SUBJECT */
	if (!strcmp (criterion+1,"EEN")) f = pgm->seen = T;
	else if (!strncmp (criterion+1,"ENT",3)) {
	  if (!strcmp (criterion+4,"BEFORE"))
	    f = mail_criteria_date (&pgm->sentbefore,&r);
	  else if (!strcmp (criterion+4,"ON"))
	    f = mail_criteria_date (&pgm->senton,&r);
	  else if (!strcmp (criterion+4,"SINCE"))
	    f = mail_criteria_date (&pgm->sentsince,&r);
	}
	else if (!strcmp (criterion+1,"INCE"))
	  f = mail_criteria_date (&pgm->since,&r);
	else if (!strcmp (criterion+1,"MALLER"))
	  f = prune_criteria_number (&pgm->smaller,&r);
	else if (!strcmp (criterion+1,"UBJECT"))
	  f = mail_criteria_string (&pgm->subject,&r);
	break;
      case 'T':			/* possible TEXT, TO */
	if (!strcmp (criterion+1,"EXT"))
	  f = mail_criteria_string (&pgm->text,&r);
	else if (!strcmp (criterion+1,"O"))
	  f = mail_criteria_string (&pgm->to,&r);
	break;
      case 'U':			/* possible UN* */
	if (criterion[1] == 'N') {
	  if (!strcmp (criterion+2,"ANSWERED")) f = pgm->unanswered = T;
	  else if (!strcmp (criterion+2,"DELETED")) f = pgm->undeleted = T;
	  else if (!strcmp (criterion+2,"DRAFT")) f = pgm->undraft = T;
	  else if (!strcmp (criterion+2,"FLAGGED")) f = pgm->unflagged = T;
	  else if (!strcmp (criterion+2,"KEYWORD"))
	    f = mail_criteria_string (&pgm->unkeyword,&r);
	  else if (!strcmp (criterion+2,"SEEN")) f = pgm->unseen = T;
	}
	break;
      default:			/* we will barf below */
	break;
      }

      if (!f) {			/* if can't identify criterion */
	sprintf (tmp,"Unknown search criterion: %.30s",criterion);
	MM_LOG (tmp,ERROR);
	mail_free_searchpgm (&pgm);
	break;
      }
    }
				/* no longer need copy of criteria */
    fs_give ((void **) &criteria);
  }
  return pgm;
}