Beispiel #1
0
/*
 * Returns the index cache entry associated with this message.
 * If it doesn't already exist it is instantiated.
 */
ICE_S *
fetch_ice(MAILSTREAM *stream, long unsigned int rawno)
{
    PINELT_S    **peltp;
    MESSAGECACHE *mc;

    if(!stream || rawno < 1L || rawno > stream->nmsgs)
      return NULL;

    if(!(mc = mail_elt(stream, rawno)))
      return NULL;

    /*
     * any private elt data yet?
     */
    if((*(peltp = (PINELT_S **) &mc->sparep) == NULL)){
	*peltp = (PINELT_S *) fs_get(sizeof(PINELT_S));
	memset(*peltp, 0, sizeof(PINELT_S));
    }

    if((*peltp)->ice == NULL)
      (*peltp)->ice = new_ice();

    if(need_format_setup(stream) && setup_header_widths)
      (*setup_header_widths)(stream);

    return((*peltp)->ice);
}
Beispiel #2
0
Variant f_imap_mailboxmsginfo(const Resource& imap_stream) {
  ImapStream *obj = imap_stream.getTyped<ImapStream>();
  Object ret(SystemLib::AllocStdClassObject());

  int64_t unreadmsg = 0, deletedmsg = 0, msize = 0;

  for (unsigned long i = 1; i <= obj->m_stream->nmsgs; i++) {
    MESSAGECACHE * cache = mail_elt (obj->m_stream, i);
    mail_fetchstructure (obj->m_stream, i, NIL);

    if (!cache->seen || cache->recent) {
      unreadmsg++;
    }

    if (cache->deleted) {
      deletedmsg++;
    }
    msize = msize + cache->rfc822_size;
  }

  ret.o_set("Unread", (int64_t)unreadmsg);
  ret.o_set("Deleted", (int64_t)deletedmsg);
  ret.o_set("Nmsgs", (int64_t)obj->m_stream->nmsgs);
  ret.o_set("Size", (int64_t)msize);

  char date[100];
  rfc822_date(date);
  ret.o_set("Date", String(date, CopyString));
  ret.o_set("Driver", String(obj->m_stream->dtb->name, CopyString));
  ret.o_set("Mailbox", String(obj->m_stream->mailbox, CopyString));
  ret.o_set("Recent", (int64_t)msize);

  return ret;
}
Beispiel #3
0
long
get_msgno_by_msg_id(MAILSTREAM *stream, char *message_id, MSGNO_S *msgmap)
{
    SEARCHPGM  *pgm = NULL;
    long        hint = mn_m2raw(msgmap, mn_get_cur(msgmap));
    long        newmsgno = -1L;
    int         iter = 0;
    MESSAGECACHE *mc;
    extern MAILSTREAM *mm_search_stream;
    extern long        mm_search_count;

    if(!(message_id && message_id[0]) || stream->nmsgs < 1L)
      return(newmsgno);

    mm_search_count = 0L;
    mm_search_stream = stream;
    while(mm_search_count == 0L && iter++ < 3
	  && (pgm = mail_newsearchpgm()) != NULL){
	pgm->message_id = mail_newstringlist();
	pgm->message_id->text.data = (unsigned char *) cpystr(message_id);
	pgm->message_id->text.size = strlen(message_id);

	if(iter > 1 || hint > stream->nmsgs)
	  iter++;

	if(iter == 1){
	    /* restrict to hint message on first try */
	    pgm->msgno = mail_newsearchset();
	    pgm->msgno->first = pgm->msgno->last = hint;
	}
	else if(iter == 2){
	    /* restrict to last 50 messages on 2nd try */
	    pgm->msgno = mail_newsearchset();
	    if(stream->nmsgs > 100L)
	      pgm->msgno->first = stream->nmsgs-50L;
	    else{
		pgm->msgno->first = 1L;
		iter++;
	    }

	    pgm->msgno->last = stream->nmsgs;
	}

	pine_mail_search_full(stream, NULL, pgm, SE_NOPREFETCH | SE_FREE);

	if(mm_search_count){
	    for(newmsgno=stream->nmsgs; newmsgno > 0L; newmsgno--)
	      if((mc = mail_elt(stream, newmsgno)) && mc->searched)
		break;
	}
    }

    return(mn_raw2m(msgmap, newmsgno));
}
Beispiel #4
0
/*----------------------------------------------------------------------
  Got thru the message mapping table, and remove messages with DELETED flag

   Accepts: stream -- mail stream to removed message references from
	    msgs -- pointer to message manipulation struct
	    f -- flags to use a purge criteria
  ----*/
void
msgno_exclude_deleted(MAILSTREAM *stream, MSGNO_S *msgs, char *sequence)
{
    long	  i, rawno;
    MESSAGECACHE *mc;
    int           need_isort_reset = 0;

    if(!msgs || msgs->max_msgno < 1L)
      return;

    /*
     * With 3.91 we're using a new strategy for finding and operating
     * on all the messages with deleted status.  The idea is to do a
     * mail_search for deleted messages so the elt's "searched" bit gets
     * set, and then to scan the elt's for them and set our local bit
     * to indicate they're excluded...
     */
    (void) count_flagged(stream, F_DEL);

    if(sequence)
	mail_sequence (stream,sequence);

    /*
     * Start with the end of the folder and work backwards so that
     * msgno_exclude doesn't have to shift the entire array each time when
     * there are lots of deleteds. In fact, if everything is deleted (like
     * might be the case in a huge newsgroup) then it never has to shift
     * anything. It is always at the end of the array just eliminating the
     * last one instead. So instead of an n**2 operation, it is n.
     */
    for(i = msgs->max_msgno; i >= 1L; i--)
      if((rawno = mn_m2raw(msgs, i)) > 0L && stream && rawno <= stream->nmsgs
	 && (mc = mail_elt(stream, rawno))
	 && (sequence ? mc->sequence : 1)
	 && ((mc->valid && mc->deleted) || (!mc->valid && mc->searched))){
	  msgno_exclude(stream, msgs, i, 0);
	  need_isort_reset++;
      }
    
    if(need_isort_reset)
      msgno_reset_isort(msgs);

    /*
     * If we excluded away a zoomed display, unhide everything...
     */
    if(msgs->max_msgno > 0L && any_lflagged(msgs, MN_HIDE) >= msgs->max_msgno)
      for(i = 1L; i <= msgs->max_msgno; i++)
	set_lflag(stream, msgs, i, MN_HIDE, 0);
}
Beispiel #5
0
/*
 * Erase a particular entry in the cache.
 */
void
clear_index_cache_ent(MAILSTREAM *stream, long int msgno, unsigned int flags)
{
    long          rawno = -1L;
    PINELT_S    **peltp;
    MESSAGECACHE *mc;

    if(stream){
	if(flags && IC_USE_RAW_MSGNO)
	  rawno = msgno;
	else
	  rawno = mn_m2raw(sp_msgmap(stream), msgno);

	if(rawno > 0L && rawno <= stream->nmsgs){
	    mc = mail_elt(stream, rawno);
	    if(mc && mc->sparep){
		peltp = (PINELT_S **) &mc->sparep;
		if((*peltp)->ice){
		    /*
		     * This is intended to be a lightweight reset of
		     * just the widths and print_format strings. For example,
		     * the width of the screen changed and nothing else.
		     * We simply unset the widths_done bit and it
		     * is up to the drawer to free and recalculate the
		     * print_format strings and to reset the widths.
		     *
		     * The else case is a clear of the entire cache entry
		     * leaving behind only the empty structure.
		     */
		    if(flags & IC_CLEAR_WIDTHS_DONE){
			(*peltp)->ice->widths_done = 0;

			/* also zero out hash value */
			(*peltp)->ice->id = 0;

			if((*peltp)->ice->tice){
			    (*peltp)->ice->tice->widths_done = 0;

			    /* also zero out hash value */
			    (*peltp)->ice->tice->id = 0;
			}
		    }
		    else
		      clear_ice(&(*peltp)->ice);
		}
	    }
	}
    }
}
  void 
  ImapClient::fetchFlags(const std::string& aHost,
                         const std::string& aUserName,
                         const std::string& aPassword,
                         const std::string& aMailbox,
                         unsigned long aMessageNumber,
                         std::vector<int>& aFlagsVector,
                         const bool aUid) {
    
#include "linkage.c"
    
    
    MAILSTREAM* lSource = getMailStream(aHost, aUserName, aPassword, aMailbox, true);
    // convert aMessageNumber to message sequence number if necessary     
    std::string lSequenceNumber;
    std::stringstream lConverter;
    lConverter << aMessageNumber;
    lConverter >> lSequenceNumber; 
    char* lSequence = const_cast<char*>(lSequenceNumber.c_str());
    
    
    
    // update cache for this message (could have changed because of a call to setFlags) 
    mail_fetchflags_full(lSource, lSequence, (aUid ? FT_UID : NIL));  
    
    if (aUid) {
      aMessageNumber = mail_msgno(lSource, aMessageNumber); 
    }     
    
    MESSAGECACHE* lCache = mail_elt(lSource, aMessageNumber);
    
    if (lCache->seen == 1) {
      aFlagsVector[0] = 1;
    }
    if (lCache->deleted == 1) {
      aFlagsVector[1] = 1;
    }
    if (lCache->flagged == 1) {
      aFlagsVector[2] = 1;
    } 
    if (lCache->answered == 1) {
      aFlagsVector[3] = 1;
    }
    if (lCache->draft == 1) {
      aFlagsVector[4] = 1;
    }
    
  }
  ENVELOPE* 
  ImapClient::fetchStructure(const std::string& aHost, 
                             const std::string& aUserName, 
                             const std::string& aPassword, 
                             const std::string& aMailbox, 
                             BODY** aBody,  
                             unsigned long aMessageNumber, 
                             bool aUid,
                             std::vector<int>& aFlagsVector) 
  {
#include "linkage.c"
    *aBody = mail_newbody(); 
    MAILSTREAM* lSource = getMailStream(aHost, aUserName, aPassword, aMailbox, true);    
    
    ENVELOPE * lResult = mail_fetchstructure_full (lSource, aMessageNumber, aBody, (aUid ? FT_UID : NIL));
    
    if (!lResult) {
      throw EmailException("WRONG_ID", "Could not get message - wrong message id.");
    }
    
    if (aUid) {
      aMessageNumber = mail_msgno(lSource, aMessageNumber);
    }
    
    MESSAGECACHE* lCache = mail_elt(lSource, aMessageNumber);
    
    if (lCache->seen == 1) {
      aFlagsVector[0] = 1;
    }
    if (lCache->deleted == 1) {
      aFlagsVector[1] = 1;
    }
    if (lCache->flagged == 1) {
      aFlagsVector[2] = 1;
    }
    if (lCache->answered == 1) {
      aFlagsVector[3] = 1;
    }
    if (lCache->draft == 1) {
      aFlagsVector[4] = 1;
    }
    
    return lResult;
    
  }
Beispiel #8
0
int
user_flag_is_set(MAILSTREAM *stream, long unsigned int rawno, char *keyword)
{
    int           j, is_set = 0;
    MESSAGECACHE *mc;

    if(stream && keyword && keyword[0]){
	if(rawno > 0L && stream
	   && rawno <= stream->nmsgs
	   && (mc = mail_elt(stream, rawno)) != NULL){
	    j = user_flag_index(stream, keyword);
	    if(j >= 0 && j < NUSERFLAGS && ((1 << j) & mc->user_flags))
	      is_set++;
	}
    }
	
    return(is_set);
}
  ENVELOPE * 
  ImapClient::fetchEnvelope(const std::string& aHost, 
                            const std::string& aUsername, 
                            const std::string& aPassword, 
                            const std::string& aMailbox, 
                            unsigned long aMessageNumber,
                            std::vector<int>& aFlagsVector,
                            const bool aUid) 
  {
#include "linkage.c"
    MAILSTREAM* lSource = getMailStream(aHost, aUsername, aPassword, aMailbox, true); 
    
    if (aUid) {
      aMessageNumber = mail_msgno(lSource, aMessageNumber);
    }
    
    ENVELOPE* lResult = mail_fetchenvelope(lSource, aMessageNumber);
    
    if (!lResult) {
      throw EmailException("WRONG_ID", "Could not get message - wrong message id.");
    }
    
    
    MESSAGECACHE* lCache = mail_elt(lSource, aMessageNumber);
    
    if (lCache->seen == 1) {
      aFlagsVector[0] = 1;
    }
    if (lCache->deleted == 1) {
      aFlagsVector[1] = 1;
    }
    if (lCache->flagged == 1) {
      aFlagsVector[2] = 1;
    }
    if (lCache->answered == 1) {
      aFlagsVector[3] = 1;
    }
    if (lCache->draft == 1) {
      aFlagsVector[4] = 1;
    }
    
    return  lResult;
    
  }
Beispiel #10
0
/*
 * Checks whether any parts of any of the messages in msgmap are marked
 * for deletion.
 */
int
msgno_any_deletedparts(MAILSTREAM *stream, MSGNO_S *msgmap)
{
    long n, rawno;
    PINELT_S  *pelt;
    PARTEX_S **partp;
    MESSAGECACHE *mc;

    for(n = mn_first_cur(msgmap); n > 0L; n = mn_next_cur(msgmap))
      if((rawno = mn_m2raw(msgmap, n)) > 0L
	 && stream && rawno <= stream->nmsgs
	 && (mc = mail_elt(stream, rawno))
	 && (pelt = (PINELT_S *) mc->sparep))
        for(partp = &pelt->exceptions; *partp; partp = &(*partp)->next)
	  if(((*partp)->handling & MSG_EX_DELETE)
	     && (*partp)->partno
	     && *(*partp)->partno != '0'
	     && isdigit((unsigned char) *(*partp)->partno))
	    return(1);

    return(0);
}
long mm_append (MAILSTREAM *stream,void *data,char **flags,char **date,
		STRING **message)
{
  char *t,*t1,tmp[MAILTMPLEN];
  unsigned long u;
  MESSAGECACHE *elt;
  APPENDPACKAGE *ap = (APPENDPACKAGE *) data;
  *flags = *date = NIL;		/* assume no flags or date */
  if (ap->flags) fs_give ((void **) &ap->flags);
  if (ap->date) fs_give ((void **) &ap->date);
  mail_gc (ap->stream,GC_TEXTS);
  if (++ap->msgno <= ap->msgmax) {
				/* initialize flag string */
    memset (t = tmp,0,MAILTMPLEN);
				/* output system flags */
    if ((elt = mail_elt (ap->stream,ap->msgno))->seen) strcat (t," \\Seen");
    if (elt->deleted) strcat (t," \\Deleted");
    if (elt->flagged) strcat (t," \\Flagged");
    if (elt->answered) strcat (t," \\Answered");
    if (elt->draft) strcat (t," \\Draft");
				/* any user flags? */
    if (!ignorep && (u = elt->user_flags)) do
      if ((t1 = ap->stream->user_flags[find_rightmost_bit (&u)]) &&
	  (MAILTMPLEN - ((t += strlen (t)) - tmp)) > (long) (2 + strlen (t1))){
	*t++ = ' ';		/* space delimiter */
	strcpy (t,t1);		/* copy the user flag */
      }
    while (u);			/* until no more user flags */
    *flags = ap->flags = cpystr (tmp + 1);
    *date = ap->date = cpystr (mail_date (tmp,elt));
    *message = ap->message;	/* message stringstruct */
    INIT (ap->message,mstring,(void *) ap,elt->rfc822_size);
  }
  else *message = NIL;		/* all done */
  return LONGT;
}
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 */
}
Beispiel #13
0
/*
 * Calculates all of the scores for the searchset and stores them in the
 * mail elts. Careful, this function uses patterns so if the caller is using
 * patterns then the caller will probably have to reset the pattern functions.
 * That is, will have to call first_pattern again with the correct type.
 *
 * Args:     stream
 *        searchset -- calculate scores for this set of messages
 *         no_fetch -- we're in a callback from c-client, don't call c-client
 *
 * Returns   1 -- ok
 *           0 -- error, because of no_fetch
 */
int
calculate_some_scores(MAILSTREAM *stream, SEARCHSET *searchset, int no_fetch)
{
    PAT_S         *pat = NULL;
    PAT_STATE      pstate;
    char          *savebits;
    long           newscore, addtoscore, score;
    int            error = 0;
    long           rflags = ROLE_SCORE;
    long           n, i;
    SEARCHSET     *s;
    MESSAGECACHE  *mc;
    HEADER_TOK_S  *hdrtok;

    dprint((7, "calculate_some_scores\n"));

    if(nonempty_patterns(rflags, &pstate)){

	/* calculate scores */
	if(searchset){
	    
	    /* this calls match_pattern which messes up searched bits */
	    savebits = (char *)fs_get((stream->nmsgs+1) * sizeof(char));
	    for(i = 1L; i <= stream->nmsgs; i++)
	      savebits[i] = (mc = mail_elt(stream, i)) ? mc->searched : 0;

	    /*
	     * First set all the scores in the searchset to zero so that they
	     * will no longer be undefined.
	     */
	    score = 0L;
	    for(s = searchset; s; s = s->next)
	      for(n = s->first; n <= s->last; n++)
		set_msg_score(stream, n, score);

	    for(pat = first_pattern(&pstate);
		!error && pat;
		pat = next_pattern(&pstate)){

		newscore = pat->action->scoreval;
		hdrtok = pat->action->scorevalhdrtok;

		/*
		 * This no_fetch probably isn't necessary since
		 * we will actually have fetched this with
		 * the envelope. Just making sure.
		 */
		if(hdrtok && no_fetch){
		    error++;
		    break;
		}

		switch(match_pattern(pat->patgrp, stream, searchset, NULL, NULL,
				     (no_fetch ? MP_IN_CCLIENT_CB : 0)
				      | (SE_NOSERVER|SE_NOPREFETCH))){
		  case 1:
		    if(!pat->action || pat->action->bogus)
		      break;

		    for(s = searchset; s; s = s->next)
		      for(n = s->first; n <= s->last; n++)
			if(n > 0L && stream && n <= stream->nmsgs
			   && (mc = mail_elt(stream, n)) && mc->searched){
			    if((score = get_msg_score(stream,n)) == SCORE_UNDEF)
			      score = 0L;
			    
			    if(hdrtok)
			      addtoscore = scorevalfrommsg(stream, n, hdrtok, no_fetch);
			    else
			      addtoscore = newscore;

			    score += addtoscore;
			    set_msg_score(stream, n, score);
			}

		    break;
		
		  case 0:
		    break;

		  case -1:
		    error++;
		    break;
		}
	    }

	    for(i = 1L; i <= stream->nmsgs; i++)
	      if((mc = mail_elt(stream, i)) != NULL)
		mc->searched = savebits[i];

	    fs_give((void **)&savebits);

	    if(error){
		/*
		 * Revert to undefined scores.
		 */
		score = SCORE_UNDEF;
		for(s = searchset; s; s = s->next)
		  for(n = s->first; n <= s->last; n++)
		    set_msg_score(stream, n, score);
	    }
	}
    }

    return(error ? 0 : 1);
}
Beispiel #14
0
/*----------------------------------------------------------------------
  return our index number for the given raw message number

   Accepts: msgs - pointer to message manipulation struct
	    msgno - number that's important
	    part
   Returns: our index number of given raw message

  ----*/
int
msgno_exceptions(MAILSTREAM *stream, long int rawno, char *part, int *bits, int set)
{
    PINELT_S **peltp;
    PARTEX_S **partp;
    MESSAGECACHE *mc;

    if(!stream || rawno < 1L || rawno > stream->nmsgs)
      return FALSE;

    /*
     * Get pointer to exceptional part list, and scan down it
     * for the requested part...
     */
    if((mc = mail_elt(stream, rawno)) && (*(peltp = (PINELT_S **) &mc->sparep)))
      for(partp = &(*peltp)->exceptions; *partp; partp = &(*partp)->next){
	  if(part){
	      if(!strcmp(part, (*partp)->partno)){
		  if(bits){
		      if(set)
			(*partp)->handling = *bits;
		      else
			*bits = (*partp)->handling;
		  }

		  return(TRUE);		/* bingo! */
	      }
	  }
	  else if(bits){
	      /*
	       * The caller provided flags, but no part.
	       * We are looking to see if the bits are set in any of the
	       * parts. This doesn't count parts with non-digit partno's (like
	       * scores) because those are used differently.
	       * any of the flags...
	       */
	      if((*partp)->partno && *(*partp)->partno &&
		 isdigit((unsigned char) *(*partp)->partno) &&
		 (*bits & (*partp)->handling) == *bits)
		return(TRUE);
	  }
	  else
	    /*
	     * The caller didn't specify a part, so
	     * they must just be interested in whether
	     * the msg had any exceptions at all...
	     */
	    return(TRUE);
      }

    if(set && part){
	if(!*peltp){
	    *peltp = (PINELT_S *) fs_get(sizeof(PINELT_S));
	    memset(*peltp, 0, sizeof(PINELT_S));
	    partp = &(*peltp)->exceptions;
	}

	(*partp)	   = (PARTEX_S *) fs_get(sizeof(PARTEX_S));
	(*partp)->partno   = cpystr(part);
	(*partp)->next	   = NULL;
	(*partp)->handling = *bits;
	return(TRUE);
    }

    if(bits)			/* init bits */
      *bits = 0;

    return(FALSE);
}
Beispiel #15
0
/*----------------------------------------------------------------------
   Accepts: stream -- mail stream to removed message references from
	    msgs -- pointer to message manipulation struct
	    flags
	      MI_REFILTERING  -- do includes appropriate for refiltering
	      MI_STATECHGONLY -- when refiltering, maybe only re-include
	                         messages which have had state changes
				 since they were originally filtered
   Returns 1 if any new messages are included (indicating that we need
              to re-sort)
	   0 if no new messages are included
  ----*/
int
msgno_include(MAILSTREAM *stream, MSGNO_S *msgs, int flags)
{
    long   i, slop, old_total, old_size;
    int    exbits, ret = 0;
    size_t len;
    MESSAGECACHE *mc;

    if(!msgs)
      return(ret);

    for(i = 1L; i <= stream->nmsgs; i++){
	if(!msgno_exceptions(stream, i, "0", &exbits, FALSE))
	  exbits = 0;

	if((((flags & MI_REFILTERING) && (exbits & MSG_EX_FILTERED)
	     && !(exbits & MSG_EX_FILED)
	     && (!(flags & MI_STATECHGONLY) || (exbits & MSG_EX_STATECHG)))
	    || (!(flags & MI_REFILTERING) && !(exbits & MSG_EX_FILTERED)))
	   && get_lflag(stream, NULL, i, MN_EXLD)){
	    old_total	     = msgs->max_msgno;
	    old_size	     = msgs->sort_size;
	    slop	     = (msgs->max_msgno + 1L) % 64;
	    msgs->sort_size  = (msgs->max_msgno + 1L) + (64 - slop);
	    len		     = (size_t) msgs->sort_size * sizeof(long);
	    if(msgs->sort){
		if(old_size != msgs->sort_size)
		  fs_resize((void **)&(msgs->sort), len);
	    }
	    else
	      msgs->sort = (long *)fs_get(len);

	    ret = 1;
	    msgs->sort[++msgs->max_msgno] = i;
	    msgs->isort[i] = msgs->max_msgno;
	    set_lflag(stream, msgs, msgs->max_msgno, MN_EXLD, 0);
	    if(flags & MI_REFILTERING){
		exbits &= ~(MSG_EX_FILTERED | MSG_EX_TESTED);
		msgno_exceptions(stream, i, "0", &exbits, TRUE);
	    }

	    if(old_total <= 0L){	/* if no previous messages, */
		if(!msgs->select){	/* select the new message   */
		    msgs->sel_size = 8L;
		    len		   = (size_t)msgs->sel_size * sizeof(long);
		    msgs->select   = (long *)fs_get(len);
		}

		msgs->sel_cnt   = 1L;
		msgs->sel_cur   = 0L;
		msgs->select[0] = 1L;
	    }
	}
	else if((flags & MI_REFILTERING)
		&& (exbits & (MSG_EX_FILTERED | MSG_EX_TESTED))
		&& !(exbits & MSG_EX_FILED)
		&& (!(exbits & MSG_EX_MANUNDEL)
		    || ((mc = mail_elt(stream, i)) && mc->deleted))
	        && (!(flags & MI_STATECHGONLY) || (exbits & MSG_EX_STATECHG))){
	    /*
	     * We get here if the message was filtered by a filter that
	     * just changes status bits (it wasn't excluded), and now also
	     * if the message was merely tested for filtering. It has also
	     * not been manually undeleted. If it was manually undeleted, we
	     * don't want to reprocess the filter, undoing the user's
	     * manual undeleting. Of course, a new pine will re check this
	     * message anyway, so the user had better be using this
	     * manual undeleting only to temporarily save him or herself
	     * from an expunge before Saving or printing or something.
	     * Also, we want to still try filtering if the message has at
	     * all been marked deleted, even if the there was any manual
	     * undeleting, since this directly precedes an expunge, we want
	     * to make sure the filter does the right thing before getting
	     * rid of the message forever.
	     */
	    exbits &= ~(MSG_EX_FILTERED | MSG_EX_TESTED);
	    msgno_exceptions(stream, i, "0", &exbits, TRUE);
	}
    }

    return(ret);
}
Beispiel #16
0
/*----------------------------------------------------------------------
  Build flags string based on requested flags and what's set in messagecache

   Args: flags -- flags to test

 Result: allocated, space-delimited flags string is returned
 ----*/
char *
flag_string(MAILSTREAM *stream, long rawno, long int flags)
{
    MESSAGECACHE *mc;
    char *p, *q, *returned_flags = NULL;
    size_t len = 0;
    int k;

    mc = (rawno > 0L && stream && rawno <= stream->nmsgs)
			    ? mail_elt(stream, rawno) : NULL;
    if(!mc)
      return returned_flags;

    if((flags & F_DEL) && mc->deleted)
      len += strlen("\\DELETED") + 1;

    if((flags & F_ANS) && mc->answered)
      len += strlen("\\ANSWERED") + 1;

    if((flags & F_FWD) && user_flag_is_set(stream, rawno, FORWARDED_FLAG))
      len += strlen(FORWARDED_FLAG) + 1;

    if((flags & F_FLAG) && mc->flagged)
      len += strlen("\\FLAGGED") + 1;

    if((flags & F_SEEN) && mc->seen)
      len += strlen("\\SEEN") + 1;

    if((flags & F_KEYWORD) && stream->user_flags){
	for(k = 0; k < NUSERFLAGS; k++){
	    if((q=stream_to_user_flag_name(stream, k))
	       && user_flag_is_set(stream, rawno, q)){
		len += strlen(q) + 1;
	    }
	}
    }

    returned_flags = (char *) fs_get((len+1) * sizeof(char));
    p = returned_flags;
    *p = '\0';

    if((flags & F_DEL) && mc->deleted)
      sstrncpy(&p, "\\DELETED ", len+1-(p-returned_flags));

    if((flags & F_ANS) && mc->answered)
      sstrncpy(&p, "\\ANSWERED ", len+1-(p-returned_flags));

    if((flags & F_FWD) && user_flag_is_set(stream, rawno, FORWARDED_FLAG)){
	sstrncpy(&p, FORWARDED_FLAG, len+1-(p-returned_flags));
	sstrncpy(&p, " ", len+1-(p-returned_flags));
    }

    if((flags & F_FLAG) && mc->flagged)
      sstrncpy(&p, "\\FLAGGED ", len+1-(p-returned_flags));

    if((flags & F_SEEN) && mc->seen)
      sstrncpy(&p, "\\SEEN ", len+1-(p-returned_flags));

    if((flags & F_KEYWORD) && stream->user_flags){
	for(k = 0; k < NUSERFLAGS; k++){
	    if((q=stream_to_user_flag_name(stream, k))
	       && user_flag_is_set(stream, rawno, q)){
		sstrncpy(&p, q, len+1-(p-returned_flags));
		sstrncpy(&p, " ", len+1-(p-returned_flags));
		len += strlen(p) + 1;
	    }
	}
    }

    if(p != returned_flags && (len+1-(p-returned_flags)>0))
      *--p = '\0';

    return returned_flags;
}
Beispiel #17
0
Variant f_imap_fetch_overview(const Resource& imap_stream, const String& sequence,
                              int64_t options /* = 0 */) {
  if (options && options != FT_UID) {
    Logger::Warning("invalid value for the options parameter");
    return false;
  }

  ImapStream *obj = imap_stream.getTyped<ImapStream>();

  Array ret(Array::Create());

  long status = (options & FT_UID)
    ? mail_uid_sequence(obj->m_stream, (unsigned char *)sequence.data())
    : mail_sequence(obj->m_stream, (unsigned char *)sequence.data());

  if (status) {
    MESSAGECACHE *elt;
    ENVELOPE *env;
    for (unsigned long i = 1; i <= obj->m_stream->nmsgs; i++) {
      if (((elt = mail_elt(obj->m_stream, i))->sequence) &&
          (env = mail_fetch_structure(obj->m_stream, i, NIL, NIL))) {

        Object myoverview(SystemLib::AllocStdClassObject());
        OBJ_SET_ENTRY(myoverview, env, "subject", subject);

        if (env->from) {
          env->from->next = NULL;
          char *address = _php_rfc822_write_address(env->from);
          if (address) {
            myoverview.o_set("from", String(address, AttachString));
          }
        }
        if (env->to) {
          env->to->next = NULL;
          char *address = _php_rfc822_write_address(env->to);
          if (address) {
            myoverview.o_set("to", String(address, AttachString));
          }
        }

        OBJ_SET_ENTRY(myoverview, env, "date",        date);
        OBJ_SET_ENTRY(myoverview, env, "message_id",  message_id);
        OBJ_SET_ENTRY(myoverview, env, "references",  references);
        OBJ_SET_ENTRY(myoverview, env, "in_reply_to", in_reply_to);

        myoverview.o_set("size",     (int64_t)elt->rfc822_size);
        myoverview.o_set("uid",      (int64_t)mail_uid(obj->m_stream, i));
        myoverview.o_set("msgno",    (int64_t)i);
        myoverview.o_set("recent",   (int64_t)elt->recent);
        myoverview.o_set("flagged",  (int64_t)elt->flagged);
        myoverview.o_set("answered", (int64_t)elt->answered);
        myoverview.o_set("deleted",  (int64_t)elt->deleted);
        myoverview.o_set("seen",     (int64_t)elt->seen);
        myoverview.o_set("draft",    (int64_t)elt->draft);

        ret.append(myoverview);
      }
    }
  }

  return ret;
}
Beispiel #18
0
Variant f_imap_headerinfo(const Resource& imap_stream, int64_t msg_number,
                          int64_t fromlength /* = 0 */,
                          int64_t subjectlength /* = 0 */,
                          const String& defaulthost /* = "" */) {
  ImapStream *obj = imap_stream.getTyped<ImapStream>();
  if (fromlength < 0 || fromlength > MAILTMPLEN) {
    Logger::Warning("From length has to be between 0 and %d", MAILTMPLEN);
    return false;
  }
  if (subjectlength < 0 || subjectlength > MAILTMPLEN) {
    Logger::Warning("Subject length has to be between 0 and %d", MAILTMPLEN);
    return false;
  }
  if (!obj->checkMsgNumber(msg_number)) {
    return false;
  }
  if (!mail_fetchstructure(obj->m_stream, msg_number, NIL)) {
    return false;
  }

  MESSAGECACHE *cache = mail_elt(obj->m_stream, msg_number);
  ENVELOPE *en = mail_fetchenvelope(obj->m_stream, msg_number);

  /* call a function to parse all the text, so that we can use the
     same function to parse text from other sources */
  Object ret = _php_make_header_object(en);

  /* now run through properties that are only going to be returned
     from a server, not text headers */
  ret.o_set("Recent",   cache->recent ? (cache->seen ? "R": "N") : " ");
  ret.o_set("Unseen",   (cache->recent | cache->seen) ? " " : "U");
  ret.o_set("Flagged",  cache->flagged  ? "F" : " ");
  ret.o_set("Answered", cache->answered ? "A" : " ");
  ret.o_set("Deleted",  cache->deleted  ? "D" : " ");
  ret.o_set("Draft",    cache->draft    ? "X" : " ");

  char dummy[2000], fulladdress[MAILTMPLEN + 1];
  snprintf(dummy, sizeof(dummy), "%4ld", cache->msgno);
  ret.o_set("Msgno", String(dummy, CopyString));

  mail_date(dummy, cache);
  ret.o_set("MailDate", String(dummy, CopyString));

  snprintf(dummy, sizeof(dummy), "%ld", cache->rfc822_size);
  ret.o_set("Size", String(dummy, CopyString));

  ret.o_set("udate", (int64_t)mail_longdate(cache));

  if (en->from && fromlength) {
    fulladdress[0] = 0x00;
    mail_fetchfrom(fulladdress, obj->m_stream, msg_number, fromlength);
    ret.o_set("fetchfrom", String(fulladdress, CopyString));
  }
  if (en->subject && subjectlength) {
    fulladdress[0] = 0x00;
    mail_fetchsubject(fulladdress, obj->m_stream, msg_number, subjectlength);
    ret.o_set("fetchsubject", String(fulladdress, CopyString));
  }

  return ret;
}