Beispiel #1
0
void
msgno_exclude(MAILSTREAM *stream, MSGNO_S *msgmap, long int msgno, int reset_isort)
{
    long i;

    /*--- clear all flags to keep our counts consistent  ---*/
    set_lflag(stream, msgmap, msgno, MN_HIDE | MN_CHID | MN_CHID2 | MN_SLCT, 0);
    set_lflag(stream, msgmap, msgno, MN_EXLD, 1); /* mark excluded */

    /* erase knowledge in sort array (shift array down) */
    for(i = msgno + 1L; i <= msgmap->max_msgno; i++)
      msgmap->sort[i-1L] = msgmap->sort[i];

    msgmap->max_msgno = MAX(0L, msgmap->max_msgno - 1L);
    if(reset_isort)
      msgno_reset_isort(msgmap);

    msgno_flush_selected(msgmap, msgno);
}
Beispiel #2
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 #3
0
/*----------------------------------------------------------------------
  Straighten out any local flag problems here.  We can't take care of
  them in the mm_exists or mm_expunged callbacks since the flags
  themselves are in an MESSAGECACHE and we're not allowed to reenter
  c-client from a callback...

 Args: stream -- mail stream to operate on
       msgmap -- messages in that stream to fix up

 Result: returns with local flags as they should be

  ----*/
void
fixup_flags(MAILSTREAM *stream, MSGNO_S *msgmap)
{
    /*
     * Deal with the case where expunged away all of the 
     * zoomed messages.  Unhide everything in that case...
     */
    if(mn_get_total(msgmap) > 0L){
	long i;

	if(any_lflagged(msgmap, MN_HIDE) >= mn_get_total(msgmap)){
	    for(i = 1L; i <= mn_get_total(msgmap); i++)
	      set_lflag(stream, msgmap, i, MN_HIDE, 0);

	    mn_set_cur(msgmap, THREADING()
				 ? first_sorted_flagged(F_NONE, stream, 0L,
				               (THREADING() ? 0 : FSF_SKIP_CHID)
					       | FSF_LAST)
				 : mn_get_total(msgmap));
	}
	else if(any_lflagged(msgmap, MN_HIDE)){
	    /*
	     * if we got here, there are some hidden messages and
	     * some not.  Make sure the current message is one
	     * that's not...
	     */
	    for(i = mn_get_cur(msgmap); i <= mn_get_total(msgmap); i++)
	      if(!msgline_hidden(stream, msgmap, i, 0)){
		  mn_set_cur(msgmap, i);
		  break;
	      }

	    for(i = mn_get_cur(msgmap); i > 0L; i--)
	      if(!msgline_hidden(stream, msgmap, i, 0)){
		  mn_set_cur(msgmap, i);
		  break;
	      }
	}
    }
}
Beispiel #4
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);
}