1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: msgno.c 854 2007-12-07 17:44:43Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2016 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include "../pith/headers.h"
20 #include "../pith/msgno.h"
21 #include "../pith/flag.h"
22 #include "../pith/mailindx.h"
23 #include "../pith/pineelt.h"
24 #include "../pith/icache.h"
27 /* internal prototypes */
28 void set_msg_score(MAILSTREAM
*, long, long);
32 * * * * Message number management functions * * *
36 /*----------------------------------------------------------------------
37 Initialize a message manipulation structure for the given total
39 Accepts: msgs - pointer to pointer to message manipulation struct
40 tot - number of messages to initialize with
43 msgno_init(MSGNO_S
**msgs
, long int tot
, SortOrder def_sort
, int def_sort_rev
)
45 long slop
= (tot
+ 1L) % 64;
52 (*msgs
) = (MSGNO_S
*)fs_get(sizeof(MSGNO_S
));
53 memset((void *)(*msgs
), 0, sizeof(MSGNO_S
));
56 (*msgs
)->sel_cur
= 0L;
57 (*msgs
)->sel_cnt
= 1L;
58 (*msgs
)->sel_size
= 8L;
59 len
= (size_t)(*msgs
)->sel_size
* sizeof(long);
61 fs_resize((void **)&((*msgs
)->select
), len
);
63 (*msgs
)->select
= (long *)fs_get(len
);
65 (*msgs
)->select
[0] = (tot
) ? 1L : 0L;
67 (*msgs
)->sort_size
= (tot
+ 1L) + (64 - slop
);
68 len
= (size_t)(*msgs
)->sort_size
* sizeof(long);
70 fs_resize((void **)&((*msgs
)->sort
), len
);
72 (*msgs
)->sort
= (long *)fs_get(len
);
74 memset((void *)(*msgs
)->sort
, 0, len
);
75 for(slop
= 1L ; slop
<= tot
; slop
++) /* reusing "slop" */
76 (*msgs
)->sort
[slop
] = slop
;
79 * If there is filtering happening, isort will become larger than sort.
80 * Sort is a list of raw message numbers in their sorted order. There
81 * are missing raw numbers because some of the messages are excluded
82 * (MN_EXLD) from the view. Isort has one entry for every raw message
83 * number, which maps to the corresponding msgno (the row in the sort
84 * array). Some of the entries in isort are not used because those
85 * messages are excluded, but the entry is still there because we want
86 * to map from rawno to message number and the row number is the rawno.
88 (*msgs
)->isort_size
= (*msgs
)->sort_size
;
90 fs_resize((void **)&((*msgs
)->isort
), len
);
92 (*msgs
)->isort
= (long *)fs_get(len
);
94 (*msgs
)->max_msgno
= tot
;
97 /* set the inverse array */
98 msgno_reset_isort(*msgs
);
100 (*msgs
)->sort_order
= def_sort
;
101 (*msgs
)->reverse_sort
= def_sort_rev
;
102 (*msgs
)->flagged_hid
= 0L;
103 (*msgs
)->flagged_exld
= 0L;
104 (*msgs
)->flagged_chid
= 0L;
105 (*msgs
)->flagged_chid2
= 0L;
106 (*msgs
)->flagged_coll
= 0L;
107 (*msgs
)->flagged_usor
= 0L;
108 (*msgs
)->flagged_tmp
= 0L;
109 (*msgs
)->flagged_stmp
= 0L;
112 * This one is the total number of messages which are flagged
113 * hid OR chid. It isn't the sum of those two because a
114 * message may be flagged both at the same time.
116 (*msgs
)->flagged_invisible
= 0L;
119 * And this keeps track of visible threads in the THRD_INDX. This is
120 * weird because a thread is visible if any of its messages are
121 * not hidden, including those that are CHID hidden. You can't just
122 * count up all the messages that are hid or chid because you would
123 * miss a thread that has its top-level message hidden but some chid
124 * message not hidden.
126 (*msgs
)->visible_threads
= -1L;
131 * Isort makes mn_raw2m fast. Alternatively, we could look through
132 * the sort array to do mn_raw2m.
135 msgno_reset_isort(MSGNO_S
*msgs
)
141 * Zero isort so raw messages numbers which don't appear in the
142 * sort array show up as undefined.
144 memset((void *) msgs
->isort
, 0,
145 (size_t) msgs
->isort_size
* sizeof(long));
147 /* fill in all the defined entries */
148 for(i
= 1L; i
<= mn_get_total(msgs
); i
++)
149 msgs
->isort
[msgs
->sort
[i
]] = i
;
155 /*----------------------------------------------------------------------
156 Release resources of a message manipulation structure
158 Accepts: msgs - pointer to message manipulation struct
160 Returns: with specified structure and its members free'd
163 msgno_give(MSGNO_S
**msgs
)
167 fs_give((void **) &((*msgs
)->sort
));
170 fs_give((void **) &((*msgs
)->isort
));
173 fs_give((void **) &((*msgs
)->select
));
175 fs_give((void **) msgs
);
181 /*----------------------------------------------------------------------
182 Release resources of a message part exception list
184 Accepts: parts -- list of parts to free
185 Returns: with specified structure and its members free'd
188 msgno_free_exceptions(PARTEX_S
**parts
)
192 msgno_free_exceptions(&(*parts
)->next
);
194 fs_give((void **) &(*parts
)->partno
);
195 fs_give((void **) parts
);
201 /*----------------------------------------------------------------------
202 Increment the current message number
204 Accepts: msgs - pointer to message manipulation struct
207 msgno_inc(MAILSTREAM
*stream
, MSGNO_S
*msgs
, int flags
)
211 if(!msgs
|| mn_get_total(msgs
) < 1L)
214 for(i
= msgs
->select
[msgs
->sel_cur
] + 1; i
<= mn_get_total(msgs
); i
++){
215 if(!msgline_hidden(stream
, msgs
, i
, flags
)){
216 (msgs
)->select
[((msgs
)->sel_cur
)] = i
;
224 /*----------------------------------------------------------------------
225 Decrement the current message number
227 Accepts: msgs - pointer to message manipulation struct
230 msgno_dec(MAILSTREAM
*stream
, MSGNO_S
*msgs
, int flags
)
234 if(!msgs
|| mn_get_total(msgs
) < 1L)
237 for(i
= (msgs
)->select
[((msgs
)->sel_cur
)] - 1L; i
>= 1L; i
--){
238 if(!msgline_hidden(stream
, msgs
, i
, flags
)){
239 (msgs
)->select
[((msgs
)->sel_cur
)] = i
;
247 /*----------------------------------------------------------------------
248 Got thru the message mapping table, and remove messages with DELETED flag
250 Accepts: stream -- mail stream to removed message references from
251 msgs -- pointer to message manipulation struct
252 f -- flags to use a purge criteria
255 msgno_exclude_deleted(MAILSTREAM
*stream
, MSGNO_S
*msgs
, char *sequence
)
259 int need_isort_reset
= 0;
261 if(!msgs
|| msgs
->max_msgno
< 1L)
265 * With 3.91 we're using a new strategy for finding and operating
266 * on all the messages with deleted status. The idea is to do a
267 * mail_search for deleted messages so the elt's "searched" bit gets
268 * set, and then to scan the elt's for them and set our local bit
269 * to indicate they're excluded...
271 (void) count_flagged(stream
, F_DEL
);
274 mail_sequence (stream
,(unsigned char *) sequence
);
277 * Start with the end of the folder and work backwards so that
278 * msgno_exclude doesn't have to shift the entire array each time when
279 * there are lots of deleteds. In fact, if everything is deleted (like
280 * might be the case in a huge newsgroup) then it never has to shift
281 * anything. It is always at the end of the array just eliminating the
282 * last one instead. So instead of an n**2 operation, it is n.
284 for(i
= msgs
->max_msgno
; i
>= 1L; i
--)
285 if((rawno
= mn_m2raw(msgs
, i
)) > 0L && stream
&& rawno
<= stream
->nmsgs
286 && (mc
= mail_elt(stream
, rawno
))
287 && (sequence
? mc
->sequence
: 1)
288 && ((mc
->valid
&& mc
->deleted
) || (!mc
->valid
&& mc
->searched
))){
289 msgno_exclude(stream
, msgs
, i
, 0);
294 msgno_reset_isort(msgs
);
297 * If we excluded away a zoomed display, unhide everything...
299 if(msgs
->max_msgno
> 0L && any_lflagged(msgs
, MN_HIDE
) >= msgs
->max_msgno
)
300 for(i
= 1L; i
<= msgs
->max_msgno
; i
++)
301 set_lflag(stream
, msgs
, i
, MN_HIDE
, 0);
307 msgno_exclude(MAILSTREAM
*stream
, MSGNO_S
*msgmap
, long int msgno
, int reset_isort
)
311 /*--- clear all flags to keep our counts consistent ---*/
312 set_lflag(stream
, msgmap
, msgno
, MN_HIDE
| MN_CHID
| MN_CHID2
| MN_SLCT
, 0);
313 set_lflag(stream
, msgmap
, msgno
, MN_EXLD
, 1); /* mark excluded */
315 /* erase knowledge in sort array (shift array down) */
316 for(i
= msgno
+ 1L; i
<= msgmap
->max_msgno
; i
++)
317 msgmap
->sort
[i
-1L] = msgmap
->sort
[i
];
319 msgmap
->max_msgno
= MAX(0L, msgmap
->max_msgno
- 1L);
321 msgno_reset_isort(msgmap
);
323 msgno_flush_selected(msgmap
, msgno
);
328 /*----------------------------------------------------------------------
329 Accepts: stream -- mail stream to removed message references from
330 msgs -- pointer to message manipulation struct
332 MI_REFILTERING -- do includes appropriate for refiltering
333 MI_STATECHGONLY -- when refiltering, maybe only re-include
334 messages which have had state changes
335 since they were originally filtered
336 Returns 1 if any new messages are included (indicating that we need
338 0 if no new messages are included
341 msgno_include(MAILSTREAM
*stream
, MSGNO_S
*msgs
, int flags
)
343 long i
, slop
, old_total
, old_size
;
351 for(i
= 1L; i
<= stream
->nmsgs
; i
++){
352 if(!msgno_exceptions(stream
, i
, "0", &exbits
, FALSE
))
355 if((((flags
& MI_REFILTERING
) && (exbits
& MSG_EX_FILTERED
)
356 && !(exbits
& MSG_EX_FILED
)
357 && (!(flags
& MI_STATECHGONLY
) || (exbits
& MSG_EX_STATECHG
)))
358 || (!(flags
& MI_REFILTERING
) && !(exbits
& MSG_EX_FILTERED
)))
359 && get_lflag(stream
, NULL
, i
, MN_EXLD
)){
360 old_total
= msgs
->max_msgno
;
361 old_size
= msgs
->sort_size
;
362 slop
= (msgs
->max_msgno
+ 1L) % 64;
363 msgs
->sort_size
= (msgs
->max_msgno
+ 1L) + (64 - slop
);
364 len
= (size_t) msgs
->sort_size
* sizeof(long);
366 if(old_size
!= msgs
->sort_size
)
367 fs_resize((void **)&(msgs
->sort
), len
);
370 msgs
->sort
= (long *)fs_get(len
);
373 msgs
->sort
[++msgs
->max_msgno
] = i
;
374 msgs
->isort
[i
] = msgs
->max_msgno
;
375 set_lflag(stream
, msgs
, msgs
->max_msgno
, MN_EXLD
, 0);
376 if(flags
& MI_REFILTERING
){
377 exbits
&= ~(MSG_EX_FILTERED
| MSG_EX_TESTED
);
378 msgno_exceptions(stream
, i
, "0", &exbits
, TRUE
);
381 if(old_total
<= 0L){ /* if no previous messages, */
382 if(!msgs
->select
){ /* select the new message */
384 len
= (size_t)msgs
->sel_size
* sizeof(long);
385 msgs
->select
= (long *)fs_get(len
);
390 msgs
->select
[0] = 1L;
393 else if((flags
& MI_REFILTERING
)
394 && (exbits
& (MSG_EX_FILTERED
| MSG_EX_TESTED
))
395 && !(exbits
& MSG_EX_FILED
)
396 && (!(exbits
& MSG_EX_MANUNDEL
)
397 || ((mc
= mail_elt(stream
, i
)) && mc
->deleted
))
398 && (!(flags
& MI_STATECHGONLY
) || (exbits
& MSG_EX_STATECHG
))){
400 * We get here if the message was filtered by a filter that
401 * just changes status bits (it wasn't excluded), and now also
402 * if the message was merely tested for filtering. It has also
403 * not been manually undeleted. If it was manually undeleted, we
404 * don't want to reprocess the filter, undoing the user's
405 * manual undeleting. Of course, a new pine will re check this
406 * message anyway, so the user had better be using this
407 * manual undeleting only to temporarily save him or herself
408 * from an expunge before Saving or printing or something.
409 * Also, we want to still try filtering if the message has at
410 * all been marked deleted, even if the there was any manual
411 * undeleting, since this directly precedes an expunge, we want
412 * to make sure the filter does the right thing before getting
413 * rid of the message forever.
415 exbits
&= ~(MSG_EX_FILTERED
| MSG_EX_TESTED
);
416 msgno_exceptions(stream
, i
, "0", &exbits
, TRUE
);
425 /*----------------------------------------------------------------------
426 Add the given number of raw message numbers to the end of the
429 Accepts: msgs - pointer to message manipulation struct
431 Returns: with fixed up msgno struct
433 Only have to adjust the sort array, as since new mail can't cause
437 msgno_add_raw(MSGNO_S
*msgs
, long int n
)
439 long slop
, islop
, old_total
, old_size
, old_isize
;
445 old_total
= msgs
->max_msgno
;
446 old_size
= msgs
->sort_size
;
447 old_isize
= msgs
->isort_size
;
448 slop
= (msgs
->max_msgno
+ n
+ 1L) % 64;
449 islop
= (msgs
->nmsgs
+ n
+ 1L) % 64;
450 msgs
->sort_size
= (msgs
->max_msgno
+ n
+ 1L) + (64 - slop
);
451 msgs
->isort_size
= (msgs
->nmsgs
+ n
+ 1L) + (64 - islop
);
452 len
= (size_t) msgs
->sort_size
* sizeof(long);
453 ilen
= (size_t) msgs
->isort_size
* sizeof(long);
455 if(old_size
!= msgs
->sort_size
)
456 fs_resize((void **) &(msgs
->sort
), len
);
459 msgs
->sort
= (long *) fs_get(len
);
462 if(old_isize
!= msgs
->isort_size
)
463 fs_resize((void **) &(msgs
->isort
), ilen
);
466 msgs
->isort
= (long *) fs_get(ilen
);
469 msgs
->sort
[++msgs
->max_msgno
] = ++msgs
->nmsgs
;
470 msgs
->isort
[msgs
->nmsgs
] = msgs
->max_msgno
;
473 if(old_total
<= 0L){ /* if no previous messages, */
474 if(!msgs
->select
){ /* select the new message */
476 len
= (size_t) msgs
->sel_size
* sizeof(long);
477 msgs
->select
= (long *) fs_get(len
);
482 msgs
->select
[0] = 1L;
487 /*----------------------------------------------------------------------
488 Remove all knowledge of the given raw message number
490 Accepts: msgs - pointer to message manipulation struct
491 rawno - number to remove
492 Returns: with fixed up msgno struct
494 After removing *all* references, adjust the sort array and
495 various pointers accordingly...
498 msgno_flush_raw(MSGNO_S
*msgs
, long int rawno
)
500 long i
, old_sorted
= 0L;
506 /* blast rawno from sort array */
507 for(i
= 1L; i
<= msgs
->max_msgno
; i
++){
508 if(msgs
->sort
[i
] == rawno
){
513 if(shift
&& i
< msgs
->max_msgno
)
514 msgs
->sort
[i
] = msgs
->sort
[i
+ 1L];
516 if(msgs
->sort
[i
] > rawno
)
520 /*---- now, fixup counts and select array ----*/
521 if(--msgs
->nmsgs
< 0)
525 if(--msgs
->max_msgno
< 0)
526 msgs
->max_msgno
= 0L;
528 msgno_flush_selected(msgs
, old_sorted
);
531 msgno_reset_isort(msgs
);
534 snprintf(b
, sizeof(b
),
535 "isort validity: end of msgno_flush_raw: rawno=%ld\n", rawno
);
540 /*----------------------------------------------------------------------
541 Remove all knowledge of the given selected message number
543 Accepts: msgs - pointer to message manipulation struct
545 Returns: with fixed up selec members in msgno struct
547 Remove reference and fix up selected message numbers beyond
551 msgno_flush_selected(MSGNO_S
*msgs
, long int n
)
556 for(i
= 0L; i
< msgs
->sel_cnt
; i
++){
557 if(!shift
&& (msgs
->select
[i
] == n
))
560 if(shift
&& i
+ 1L < msgs
->sel_cnt
)
561 msgs
->select
[i
] = msgs
->select
[i
+ 1L];
563 if(n
< msgs
->select
[i
] || msgs
->select
[i
] > msgs
->max_msgno
)
564 msgs
->select
[i
] -= 1L;
567 if(shift
&& msgs
->sel_cnt
> 1L)
573 msgno_set_sort(MSGNO_S
*msgs
, SortOrder sort
)
576 if(sort
== SortScore
)
577 scores_are_used(SCOREUSE_INVALID
);
579 msgs
->sort_order
= sort
;
584 /*----------------------------------------------------------------------
585 Test to see if the given message number is in the selected message
588 Accepts: msgs - pointer to message manipulation struct
590 Returns: true if n is in selected array, false otherwise
594 msgno_in_select(MSGNO_S
*msgs
, long int n
)
599 for(i
= 0L; i
< msgs
->sel_cnt
; i
++)
600 if(msgs
->select
[i
] == n
)
608 /*----------------------------------------------------------------------
609 return our index number for the given raw message number
611 Accepts: msgs - pointer to message manipulation struct
612 msgno - number that's important
614 Returns: our index number of given raw message
618 msgno_exceptions(MAILSTREAM
*stream
, long int rawno
, char *part
, int *bits
, int set
)
624 if(!stream
|| rawno
< 1L || rawno
> stream
->nmsgs
)
628 * Get pointer to exceptional part list, and scan down it
629 * for the requested part...
631 if((mc
= mail_elt(stream
, rawno
)) && (*(peltp
= (PINELT_S
**) &mc
->sparep
)))
632 for(partp
= &(*peltp
)->exceptions
; *partp
; partp
= &(*partp
)->next
){
634 if(!strcmp(part
, (*partp
)->partno
)){
637 (*partp
)->handling
= *bits
;
639 *bits
= (*partp
)->handling
;
642 return(TRUE
); /* bingo! */
647 * The caller provided flags, but no part.
648 * We are looking to see if the bits are set in any of the
649 * parts. This doesn't count parts with non-digit partno's (like
650 * scores) because those are used differently.
651 * any of the flags...
653 if((*partp
)->partno
&& *(*partp
)->partno
&&
654 isdigit((unsigned char) *(*partp
)->partno
) &&
655 (*bits
& (*partp
)->handling
) == *bits
)
660 * The caller didn't specify a part, so
661 * they must just be interested in whether
662 * the msg had any exceptions at all...
669 *peltp
= (PINELT_S
*) fs_get(sizeof(PINELT_S
));
670 memset(*peltp
, 0, sizeof(PINELT_S
));
671 partp
= &(*peltp
)->exceptions
;
674 (*partp
) = (PARTEX_S
*) fs_get(sizeof(PARTEX_S
));
675 (*partp
)->partno
= cpystr(part
);
676 (*partp
)->next
= NULL
;
677 (*partp
)->handling
= *bits
;
681 if(bits
) /* init bits */
689 * Checks whether any parts of any of the messages in msgmap are marked
693 msgno_any_deletedparts(MAILSTREAM
*stream
, MSGNO_S
*msgmap
)
700 for(n
= mn_first_cur(msgmap
); n
> 0L; n
= mn_next_cur(msgmap
))
701 if((rawno
= mn_m2raw(msgmap
, n
)) > 0L
702 && stream
&& rawno
<= stream
->nmsgs
703 && (mc
= mail_elt(stream
, rawno
))
704 && (pelt
= (PINELT_S
*) mc
->sparep
))
705 for(partp
= &pelt
->exceptions
; *partp
; partp
= &(*partp
)->next
)
706 if(((*partp
)->handling
& MSG_EX_DELETE
)
708 && *(*partp
)->partno
!= '0'
709 && isdigit((unsigned char) *(*partp
)->partno
))
717 msgno_part_deleted(MAILSTREAM
*stream
, long int rawno
, char *part
)
723 * Is this attachment or any of it's parents in the
724 * MIME structure marked for deletion?
726 for(p
= part
; p
&& *p
; p
= strindex(++p
, '.')){
730 (void) msgno_exceptions(stream
, rawno
, part
, &expbits
, FALSE
);
734 if(expbits
& MSG_EX_DELETE
)
738 /* Finally, check if the whole message body's deleted */
739 return(msgno_exceptions(stream
, rawno
, "", &expbits
, FALSE
)
740 ? (expbits
& MSG_EX_DELETE
) : FALSE
);
746 * Set the score for a message to score, which can be anything including
750 set_msg_score(MAILSTREAM
*stream
, long int rawmsgno
, long int score
)
754 /* scores are between SCORE_MIN and SCORE_MAX, so ok */
755 intscore
= (int) score
;
757 (void) msgno_exceptions(stream
, rawmsgno
, "S", &intscore
, TRUE
);
762 * Returns the score for a message. If that score is undefined the value
763 * returned will be SCORE_UNDEF, so the caller has to be prepared for that.
764 * The caller should calculate the undefined scores before calling this.
767 get_msg_score(MAILSTREAM
*stream
, long int rawmsgno
)
772 if(msgno_exceptions(stream
, rawmsgno
, "S", &s
, FALSE
))
782 clear_msg_score(MAILSTREAM
*stream
, long int rawmsgno
)
787 set_msg_score(stream
, rawmsgno
, SCORE_UNDEF
);
792 * Set all the score values to undefined.
795 clear_folder_scores(MAILSTREAM
*stream
)
802 for(n
= 1L; n
<= stream
->nmsgs
; n
++)
803 clear_msg_score(stream
, n
);
808 * Calculates all of the scores for the searchset and stores them in the
809 * mail elts. Careful, this function uses patterns so if the caller is using
810 * patterns then the caller will probably have to reset the pattern functions.
811 * That is, will have to call first_pattern again with the correct type.
814 * searchset -- calculate scores for this set of messages
815 * no_fetch -- we're in a callback from c-client, don't call c-client
818 * 0 -- error, because of no_fetch
821 calculate_some_scores(MAILSTREAM
*stream
, SEARCHSET
*searchset
, int no_fetch
)
826 long newscore
, addtoscore
, score
;
828 long rflags
= ROLE_SCORE
;
832 HEADER_TOK_S
*hdrtok
;
834 dprint((7, "calculate_some_scores\n"));
836 if(nonempty_patterns(rflags
, &pstate
)){
838 /* calculate scores */
841 /* this calls match_pattern which messes up searched bits */
842 savebits
= (char *)fs_get((stream
->nmsgs
+1) * sizeof(char));
843 for(i
= 1L; i
<= stream
->nmsgs
; i
++)
844 savebits
[i
] = (mc
= mail_elt(stream
, i
)) ? mc
->searched
: 0;
847 * First set all the scores in the searchset to zero so that they
848 * will no longer be undefined.
851 for(s
= searchset
; s
; s
= s
->next
)
852 for(n
= s
->first
; n
<= s
->last
; n
++)
853 set_msg_score(stream
, n
, score
);
855 for(pat
= first_pattern(&pstate
);
857 pat
= next_pattern(&pstate
)){
859 newscore
= pat
->action
->scoreval
;
860 hdrtok
= pat
->action
->scorevalhdrtok
;
863 * This no_fetch probably isn't necessary since
864 * we will actually have fetched this with
865 * the envelope. Just making sure.
867 if(hdrtok
&& no_fetch
){
872 switch(match_pattern(pat
->patgrp
, stream
, searchset
, NULL
, NULL
,
873 (no_fetch
? MP_IN_CCLIENT_CB
: 0)
874 | (SE_NOSERVER
|SE_NOPREFETCH
))){
876 if(!pat
->action
|| pat
->action
->bogus
)
879 for(s
= searchset
; s
; s
= s
->next
)
880 for(n
= s
->first
; n
<= s
->last
; n
++)
881 if(n
> 0L && stream
&& n
<= stream
->nmsgs
882 && (mc
= mail_elt(stream
, n
)) && mc
->searched
){
883 if((score
= get_msg_score(stream
,n
)) == SCORE_UNDEF
)
887 addtoscore
= scorevalfrommsg(stream
, n
, hdrtok
, no_fetch
);
889 addtoscore
= newscore
;
892 set_msg_score(stream
, n
, score
);
906 for(i
= 1L; i
<= stream
->nmsgs
; i
++)
907 if((mc
= mail_elt(stream
, i
)) != NULL
)
908 mc
->searched
= savebits
[i
];
910 fs_give((void **)&savebits
);
914 * Revert to undefined scores.
917 for(s
= searchset
; s
; s
= s
->next
)
918 for(n
= s
->first
; n
<= s
->last
; n
++)
919 set_msg_score(stream
, n
, score
);
924 return(error
? 0 : 1);
929 free_pine_elt(void **sparep
)
933 peltp
= (PINELT_S
**) sparep
;
936 msgno_free_exceptions(&(*peltp
)->exceptions
);
938 fs_give((void **) &(*peltp
)->pthrd
);
941 free_ice(&(*peltp
)->ice
);
943 fs_give((void **) peltp
);