Beispiel #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;
  }
int main (int argc,char *argv[])
{
  MAILSTREAM *source = NIL;
  MAILSTREAM *dest = NIL;
  SEARCHPGM *criteria;
  char c,*s,*dp,*t,*t1,tmp[MAILTMPLEN],mbx[MAILTMPLEN];
  unsigned long m,len,curlen,start,last;
  int i;
  int merge = NIL;
  int retcode = 1;
  int moreswitchp = T;
  char *cmd = NIL;
  char *src = NIL;
  char *dst = NIL;
  char *pgm = argc ? argv[0] : "mailutil";
#include "linkage.c"
  for (i = 1; i < argc; i++) {
    s = argv[i];		/* pick up argument */
				/* parse switches */
    if (moreswitchp && (*s == '-')) {
      if (!strcmp (s,"-debug") || !strcmp (s,"-d")) debugp = T;
      else if (!strcmp (s,"-verbose") || !strcmp (s,"-v")) verbosep = T;
      else if (!strcmp (s,"-rwcopy") || !strcmp (s,"-rw")) rwcopyp = T;
      else if (!strcmp (s,"-kwcopy") || !strcmp (s,"-kw")) kwcopyp = T;
      else if (!strcmp (s,"-ignore") || !strcmp (s,"-ig")) ignorep = T;
      else if ((!strcmp (s,"-merge") || !strcmp (s,"-m")) && (++i < argc)) {
	if (!strcmp (s = argv[i],"prompt")) merge = mPROMPT;
	else if (!strcmp (s,"append")) merge = mAPPEND;
	else if (!strncmp (s,"suffix=",7) && s[7]) {
	  merge = mSUFFIX;
	  suffix = cpystr (s+7);
	}
	else {
	  printf ("unknown merge option: %s\n",s);
	  exit (retcode);
	}
      }

#ifdef SYSCONFIG
      else if ((!strcmp (s,"-user") || !strcmp (s,"-u")) && (++i < argc)) {
	struct passwd *pw = getpwnam (s = argv[i]);
	if (!pw) {
	  printf ("unknown user id: %s\n",argv[i]);
	  exit (retcode);
	}
	else if (setuid (pw->pw_uid)) {
	  perror ("unable to change user id");
	  exit (retcode);
	}
      }
#endif
				/* -- means no more switches, so mailbox
				   name can start with "-" */
      else if ((s[1] == '-') && !s[2]) moreswitchp = NIL;
      else {
	printf ("unknown switch: %s\n",s);
	exit (retcode);
      }
    }
    else if (!cmd) cmd = s;	/* first non-switch is command */
    else if (!src) src = s;	/* second non-switch is source */
    else if (!dst) dst = s;	/* third non-switch is destination */
    else {
      printf ("unknown argument: %s\n",s);
      exit (retcode);
    }
  }
  if (kwcopyp && ignorep) {
    puts ("-kwcopy and -ignore are mutually exclusive");
    exit (retcode);
  }
  if (!cmd) cmd = "";		/* prevent SEGV */

  if (!strcmp (cmd,"check")) {	/* check for new messages */
    if (!src) src = "INBOX";
    if (dst || merge || rwcopyp || kwcopyp || ignorep)
      printf (usage2,pgm,usgchk,stdsw);
    else if (mail_status (source = (*src == '{') ?
			  mail_open (NIL,src,OP_HALFOPEN |
				     (debugp ? OP_DEBUG : NIL)) : NIL,
			  src,SA_MESSAGES | SA_RECENT | SA_UNSEEN))
      retcode = 0;
  }
  else if (!strcmp (cmd,"create")) {
    if (!src || dst || merge || rwcopyp || kwcopyp || ignorep)
      printf (usage2,pgm,usgcre,stdsw);
    else if (mail_create (source = (*src == '{') ?
			  mail_open (NIL,src,OP_HALFOPEN |
				     (debugp ? OP_DEBUG : NIL)) : NIL,src))
      retcode = 0;
  }
  else if (!strcmp (cmd,"delete")) {
    if (!src || dst || merge || rwcopyp || kwcopyp || ignorep)
      printf (usage2,pgm,usgdel,stdsw);
    else if (mail_delete (source = (*src == '{') ?
			  mail_open (NIL,src,OP_HALFOPEN |
				     (debugp ? OP_DEBUG : NIL)) : NIL,src))
      retcode = 0;
  }
  else if (!strcmp (cmd,"rename")) {
    if (!src || !dst || merge || rwcopyp || kwcopyp || ignorep)
      printf (usage2,pgm,usgren,stdsw);
    else if (mail_rename (source = (*src == '{') ?
			  mail_open (NIL,src,OP_HALFOPEN |
				     (debugp ? OP_DEBUG : NIL)) : NIL,src,dst))
      retcode = 0;
  }

  else if ((i = !strcmp (cmd,"move")) || !strcmp (cmd,"copy")) {
    if (!src || !dst || merge) printf (usage3,pgm,cmd,usgcpymov,stdsw);
    else if (source = mail_open (NIL,src,((i || rwcopyp) ? NIL : OP_READONLY) |
				 (debugp ? OP_DEBUG : NIL))) {
      dest = NIL;		/* open destination stream if network */
      if ((*dst != '{') || (dest = mail_open (NIL,dst,OP_HALFOPEN |
					      (debugp ? OP_DEBUG : NIL)))) {
	if (mbxcopy (source,dest,dst,T,i,merge)) retcode = 0;
      }
    }
  }
  else if ((i = !strcmp (cmd,"appenddelete")) || !strcmp (cmd,"append")) {
    if (!src || !dst || merge) printf (usage3,pgm,cmd,usgappdel,stdsw);
    else if (source = mail_open (NIL,src,((i || rwcopyp) ? NIL : OP_READONLY) |
				 (debugp ? OP_DEBUG : NIL))) {
      dest = NIL;		/* open destination stream if network */
      if ((*dst != '{') || (dest = mail_open (NIL,dst,OP_HALFOPEN |
					      (debugp ? OP_DEBUG : NIL)))) {
	if (mbxcopy (source,dest,dst,NIL,i,merge)) retcode = 0;
      }
    }
  }

  else if (!strcmp (cmd,"prune")) {
    if (!src || !dst || merge || rwcopyp || kwcopyp || ignorep ||
	!(criteria = prune_criteria (dst))) printf (usage2,pgm,usgprn,stdsw);
    else if ((source = mail_open (NIL,src,(debugp ? OP_DEBUG : NIL))) &&
	     mail_search_full (source,NIL,criteria,SE_FREE)) {
      for (m = 1, s = t = NIL, len = start = last = 0; m <= source->nmsgs; m++)
	if (mail_elt (source,m)->searched) {
	  if (s) {		/* continuing a range? */
	    if (m == last + 1) last = m;
	    else {		/* no, end of previous range? */
	      if (last != start) sprintf (t,":%lu,%lu",last,m);
				/* no, just this message */
	      else sprintf (t,",%lu",m);
	      start = last = m;	/* either way, start new range */
				/* running out of space? */
	      if ((len - (curlen = (t += strlen (t)) - s)) < 20) {
		fs_resize ((void **) &s,len += MAILTMPLEN);
		t = s + curlen;	/* relocate current pointer */
	      }
	    }
	  }
	  else {		/* first time, start new buffer */
	    s = (char *) fs_get (len = MAILTMPLEN);
	    sprintf (s,"%lu",start = last = m);
	    t = s + strlen (s);	/* end of buffer */
	  }
	}
				/* finish last range if necessary */
      if (last != start) sprintf (t,":%lu",last);
      if (s) {			/* delete/expunge any matching messages */
	mail_flag (source,s,"\\Deleted",ST_SET);
	m = source->nmsgs;	/* get number of messages before purge */
	mail_expunge (source);
	printf ("%lu message(s) purged\n",m - source->nmsgs);
	fs_give ((void **) &s);	/* flush buffer */
      }
      else puts ("No matching messages, so nothing purged");
      source = mail_close (source);
    }
  }

  else if (!strcmp (cmd,"transfer")) {
    if (!src || !dst) printf (usage2,pgm,usgxfr,stdsw);
    else if ((*src == '{') &&	/* open source mailbox */
	     !(source = mail_open (NIL,src,OP_HALFOPEN |
				   (debugp ? OP_DEBUG : NIL))));
    else if ((*dst == '{') &&	/* open destination server */
	     !(dest = mail_open (NIL,dst,OP_HALFOPEN |
				 (debugp ? OP_DEBUG : NIL))));
    else if (!(f = tmpfile ())) puts ("can't open temporary file");
    else {
      if (verbosep) puts ("Listing mailboxes...");
      if (dest) strcpy (strchr (strcpy (tmp,dest->mailbox),'}') + 1,
			dp = strchr (dst,'}') + 1);
      else {
	dp = dst;
	tmp[0] = '\0';
      }
      mail_list (dest,tmp,"");
      rewind (f);		/* list all mailboxes matching prefix */
      if (ddelim < 0) {		/* if server failed to give delimiter */
	puts ("warning: unable to get destination hierarchy delimiter!");
	ddelim = 0;		/* default to none */
      }
      if (source) strcpy (strchr (strcpy (tmp,source->mailbox),'}') + 1,
			  strchr (src,'}') + 1);
      else strcpy (tmp,src);
      mail_list (source,tmp,"*");
      rewind (f);
				/* read back mailbox names */
      for (retcode = 0; !retcode && (fgets (tmp,MAILTMPLEN-1,f)); ) {
	if (t = strchr (tmp+1,'\n')) *t = '\0';
	for (t = mbx,t1 = dest ? dest->mailbox : "",c = NIL; (c != '}') && *t1;
	     *t++ = c= *t1++);
	for (t1 = dp; *t1; *t++ = *t1++);
				/* point to name without delim or netspec */
	t1 = source ? (strchr (tmp+1,'}') + 1) : tmp + 1;
				/* src and mbx have different delimiters? */
	if (ddelim && (ddelim != tmp[0]))
	  while (c = *t1++) {	/* swap delimiters then */
	    if (c == ddelim) c = tmp[0] ? tmp[0] : 'x';
	    else if (c == tmp[0]) c = ddelim;
	    *t++ = c;
	  }
				/* easy case */
	else while (*t1) *t++ = *t1++;
	*t++ = '\0';
	if (verbosep) {
	  printf ("Copying %s\n  => %s\n",tmp+1,mbx);
	  fflush (stdout);
	}
	if (source = mail_open (source,tmp+1,(debugp ? OP_DEBUG : NIL) | 
				(rwcopyp ? NIL : OP_READONLY))) {
	  if (!mbxcopy (source,dest,mbx,T,NIL,merge)) retcode = 1;
	  if (source->dtb->flags & DR_LOCAL) source = mail_close (source);
	}
	else printf ("can't open source mailbox %s\n",tmp+1);
      }
    }
  }

  else {
    printf ("%s version %s.%s\n\n",pgm,CCLIENTVERSION,version);
    printf (usage2,pgm,"command [switches] arguments",stdsw);
    printf ("\nCommands:\n %s\n",usgchk);
    puts   ("   ;; report number of messages and new messages");
    printf (" %s\n",usgcre);
    puts   ("   ;; create new mailbox");
    printf (" %s\n",usgdel);
    puts   ("   ;; delete existing mailbox");
    printf (" %s\n",usgren);
    puts   ("   ;; rename mailbox to a new name");
    printf (" copy %s\n",usgcpymov);
    printf (" move %s\n",usgcpymov);
    puts   ("   ;; create new mailbox and copy/move messages");
    printf (" append %s\n",usgappdel);
    printf (" appenddelete %s\n",usgappdel);
    puts   ("   ;; copy/move messages to existing mailbox");
    printf (" %s\n",usgprn);
    puts   ("   ;; prune mailbox of messages matching criteria");
    printf (" %s\n",usgxfr);
    puts   ("   ;; copy source hierarchy to destination");
    puts   ("   ;;  -merge modes are prompt, append, or suffix=xxxx");
  }
				/* close streams */
  if (source) mail_close (source);
  if (dest) mail_close (dest);
  exit (retcode);
  return retcode;		/* stupid compilers */
}