2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2007 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
15 #include "../pith/headers.h"
16 #include "../pith/msgno.h"
17 #include "../pith/flag.h"
18 #include "../pith/mailindx.h"
19 #include "../pith/pineelt.h"
20 #include "../pith/icache.h"
23 /* internal prototypes */
24 void set_msg_score(MAILSTREAM
*, long, long);
28 * * * * Message number management functions * * *
32 /*----------------------------------------------------------------------
33 Initialize a message manipulation structure for the given total
35 Accepts: msgs - pointer to pointer to message manipulation struct
36 tot - number of messages to initialize with
39 msgno_init(MSGNO_S
**msgs
, long int tot
, SortOrder def_sort
, int def_sort_rev
)
41 long slop
= (tot
+ 1L) % 64;
48 (*msgs
) = (MSGNO_S
*)fs_get(sizeof(MSGNO_S
));
49 memset((void *)(*msgs
), 0, sizeof(MSGNO_S
));
52 (*msgs
)->sel_cur
= 0L;
53 (*msgs
)->sel_cnt
= 1L;
54 (*msgs
)->sel_size
= 8L;
55 len
= (size_t)(*msgs
)->sel_size
* sizeof(long);
57 fs_resize((void **)&((*msgs
)->select
), len
);
59 (*msgs
)->select
= (long *)fs_get(len
);
61 (*msgs
)->select
[0] = (tot
) ? 1L : 0L;
63 (*msgs
)->sort_size
= (tot
+ 1L) + (64 - slop
);
64 len
= (size_t)(*msgs
)->sort_size
* sizeof(long);
66 fs_resize((void **)&((*msgs
)->sort
), len
);
68 (*msgs
)->sort
= (long *)fs_get(len
);
70 memset((void *)(*msgs
)->sort
, 0, len
);
71 for(slop
= 1L ; slop
<= tot
; slop
++) /* reusing "slop" */
72 (*msgs
)->sort
[slop
] = slop
;
75 * If there is filtering happening, isort will become larger than sort.
76 * Sort is a list of raw message numbers in their sorted order. There
77 * are missing raw numbers because some of the messages are excluded
78 * (MN_EXLD) from the view. Isort has one entry for every raw message
79 * number, which maps to the corresponding msgno (the row in the sort
80 * array). Some of the entries in isort are not used because those
81 * messages are excluded, but the entry is still there because we want
82 * to map from rawno to message number and the row number is the rawno.
84 (*msgs
)->isort_size
= (*msgs
)->sort_size
;
86 fs_resize((void **)&((*msgs
)->isort
), len
);
88 (*msgs
)->isort
= (long *)fs_get(len
);
90 (*msgs
)->max_msgno
= tot
;
93 /* set the inverse array */
94 msgno_reset_isort(*msgs
);
96 (*msgs
)->sort_order
= def_sort
;
97 (*msgs
)->reverse_sort
= def_sort_rev
;
98 (*msgs
)->flagged_hid
= 0L;
99 (*msgs
)->flagged_exld
= 0L;
100 (*msgs
)->flagged_chid
= 0L;
101 (*msgs
)->flagged_chid2
= 0L;
102 (*msgs
)->flagged_coll
= 0L;
103 (*msgs
)->flagged_usor
= 0L;
104 (*msgs
)->flagged_tmp
= 0L;
105 (*msgs
)->flagged_stmp
= 0L;
108 * This one is the total number of messages which are flagged
109 * hid OR chid. It isn't the sum of those two because a
110 * message may be flagged both at the same time.
112 (*msgs
)->flagged_invisible
= 0L;
115 * And this keeps track of visible threads in the THRD_INDX. This is
116 * weird because a thread is visible if any of its messages are
117 * not hidden, including those that are CHID hidden. You can't just
118 * count up all the messages that are hid or chid because you would
119 * miss a thread that has its top-level message hidden but some chid
120 * message not hidden.
122 (*msgs
)->visible_threads
= -1L;
127 * Isort makes mn_raw2m fast. Alternatively, we could look through
128 * the sort array to do mn_raw2m.
131 msgno_reset_isort(MSGNO_S
*msgs
)
137 * Zero isort so raw messages numbers which don't appear in the
138 * sort array show up as undefined.
140 memset((void *) msgs
->isort
, 0,
141 (size_t) msgs
->isort_size
* sizeof(long));
143 /* fill in all the defined entries */
144 for(i
= 1L; i
<= mn_get_total(msgs
); i
++)
145 msgs
->isort
[msgs
->sort
[i
]] = i
;
151 /*----------------------------------------------------------------------
152 Release resources of a message manipulation structure
154 Accepts: msgs - pointer to message manipulation struct
156 Returns: with specified structure and its members free'd
159 msgno_give(MSGNO_S
**msgs
)
163 fs_give((void **) &((*msgs
)->sort
));
166 fs_give((void **) &((*msgs
)->isort
));
169 fs_give((void **) &((*msgs
)->select
));
171 fs_give((void **) msgs
);
177 /*----------------------------------------------------------------------
178 Release resources of a message part exception list
180 Accepts: parts -- list of parts to free
181 Returns: with specified structure and its members free'd
184 msgno_free_exceptions(PARTEX_S
**parts
)
188 msgno_free_exceptions(&(*parts
)->next
);
190 fs_give((void **) &(*parts
)->partno
);
191 fs_give((void **) parts
);
197 /*----------------------------------------------------------------------
198 Increment the current message number
200 Accepts: msgs - pointer to message manipulation struct
203 msgno_inc(MAILSTREAM
*stream
, MSGNO_S
*msgs
, int flags
)
207 if(!msgs
|| mn_get_total(msgs
) < 1L)
210 for(i
= msgs
->select
[msgs
->sel_cur
] + 1; i
<= mn_get_total(msgs
); i
++){
211 if(!msgline_hidden(stream
, msgs
, i
, flags
)){
212 (msgs
)->select
[((msgs
)->sel_cur
)] = i
;
220 /*----------------------------------------------------------------------
221 Decrement the current message number
223 Accepts: msgs - pointer to message manipulation struct
226 msgno_dec(MAILSTREAM
*stream
, MSGNO_S
*msgs
, int flags
)
230 if(!msgs
|| mn_get_total(msgs
) < 1L)
233 for(i
= (msgs
)->select
[((msgs
)->sel_cur
)] - 1L; i
>= 1L; i
--){
234 if(!msgline_hidden(stream
, msgs
, i
, flags
)){
235 (msgs
)->select
[((msgs
)->sel_cur
)] = i
;
243 /*----------------------------------------------------------------------
244 Got thru the message mapping table, and remove messages with DELETED flag
246 Accepts: stream -- mail stream to removed message references from
247 msgs -- pointer to message manipulation struct
248 f -- flags to use a purge criteria
251 msgno_exclude_deleted(MAILSTREAM
*stream
, MSGNO_S
*msgs
, char *sequence
)
255 int need_isort_reset
= 0;
257 if(!msgs
|| msgs
->max_msgno
< 1L)
261 * With 3.91 we're using a new strategy for finding and operating
262 * on all the messages with deleted status. The idea is to do a
263 * mail_search for deleted messages so the elt's "searched" bit gets
264 * set, and then to scan the elt's for them and set our local bit
265 * to indicate they're excluded...
267 (void) count_flagged(stream
, F_DEL
);
270 mail_sequence (stream
,(unsigned char *) sequence
);
273 * Start with the end of the folder and work backwards so that
274 * msgno_exclude doesn't have to shift the entire array each time when
275 * there are lots of deleteds. In fact, if everything is deleted (like
276 * might be the case in a huge newsgroup) then it never has to shift
277 * anything. It is always at the end of the array just eliminating the
278 * last one instead. So instead of an n**2 operation, it is n.
280 for(i
= msgs
->max_msgno
; i
>= 1L; i
--)
281 if((rawno
= mn_m2raw(msgs
, i
)) > 0L && stream
&& rawno
<= stream
->nmsgs
282 && (mc
= mail_elt(stream
, rawno
))
283 && (sequence
? mc
->sequence
: 1)
284 && ((mc
->valid
&& mc
->deleted
) || (!mc
->valid
&& mc
->searched
))){
285 msgno_exclude(stream
, msgs
, i
, 0);
290 msgno_reset_isort(msgs
);
293 * If we excluded away a zoomed display, unhide everything...
295 if(msgs
->max_msgno
> 0L && any_lflagged(msgs
, MN_HIDE
) >= msgs
->max_msgno
)
296 for(i
= 1L; i
<= msgs
->max_msgno
; i
++)
297 set_lflag(stream
, msgs
, i
, MN_HIDE
, 0);
303 msgno_exclude(MAILSTREAM
*stream
, MSGNO_S
*msgmap
, long int msgno
, int reset_isort
)
307 /*--- clear all flags to keep our counts consistent ---*/
308 set_lflag(stream
, msgmap
, msgno
, MN_HIDE
| MN_CHID
| MN_CHID2
| MN_SLCT
, 0);
309 set_lflag(stream
, msgmap
, msgno
, MN_EXLD
, 1); /* mark excluded */
311 /* erase knowledge in sort array (shift array down) */
312 for(i
= msgno
+ 1L; i
<= msgmap
->max_msgno
; i
++)
313 msgmap
->sort
[i
-1L] = msgmap
->sort
[i
];
315 msgmap
->max_msgno
= MAX(0L, msgmap
->max_msgno
- 1L);
317 msgno_reset_isort(msgmap
);
319 msgno_flush_selected(msgmap
, msgno
);
324 /*----------------------------------------------------------------------
325 Accepts: stream -- mail stream to removed message references from
326 msgs -- pointer to message manipulation struct
328 MI_REFILTERING -- do includes appropriate for refiltering
329 MI_STATECHGONLY -- when refiltering, maybe only re-include
330 messages which have had state changes
331 since they were originally filtered
332 Returns 1 if any new messages are included (indicating that we need
334 0 if no new messages are included
337 msgno_include(MAILSTREAM
*stream
, MSGNO_S
*msgs
, int flags
)
339 long i
, slop
, old_total
, old_size
;
347 for(i
= 1L; i
<= stream
->nmsgs
; i
++){
348 if(!msgno_exceptions(stream
, i
, "0", &exbits
, FALSE
))
351 if((((flags
& MI_REFILTERING
) && (exbits
& MSG_EX_FILTERED
)
352 && !(exbits
& MSG_EX_FILED
)
353 && (!(flags
& MI_STATECHGONLY
) || (exbits
& MSG_EX_STATECHG
)))
354 || (!(flags
& MI_REFILTERING
) && !(exbits
& MSG_EX_FILTERED
)))
355 && get_lflag(stream
, NULL
, i
, MN_EXLD
)){
356 old_total
= msgs
->max_msgno
;
357 old_size
= msgs
->sort_size
;
358 slop
= (msgs
->max_msgno
+ 1L) % 64;
359 msgs
->sort_size
= (msgs
->max_msgno
+ 1L) + (64 - slop
);
360 len
= (size_t) msgs
->sort_size
* sizeof(long);
362 if(old_size
!= msgs
->sort_size
)
363 fs_resize((void **)&(msgs
->sort
), len
);
366 msgs
->sort
= (long *)fs_get(len
);
369 msgs
->sort
[++msgs
->max_msgno
] = i
;
370 msgs
->isort
[i
] = msgs
->max_msgno
;
371 set_lflag(stream
, msgs
, msgs
->max_msgno
, MN_EXLD
, 0);
372 if(flags
& MI_REFILTERING
){
373 exbits
&= ~(MSG_EX_FILTERED
| MSG_EX_TESTED
);
374 msgno_exceptions(stream
, i
, "0", &exbits
, TRUE
);
377 if(old_total
<= 0L){ /* if no previous messages, */
378 if(!msgs
->select
){ /* select the new message */
380 len
= (size_t)msgs
->sel_size
* sizeof(long);
381 msgs
->select
= (long *)fs_get(len
);
386 msgs
->select
[0] = 1L;
389 else if((flags
& MI_REFILTERING
)
390 && (exbits
& (MSG_EX_FILTERED
| MSG_EX_TESTED
))
391 && !(exbits
& MSG_EX_FILED
)
392 && (!(exbits
& MSG_EX_MANUNDEL
)
393 || ((mc
= mail_elt(stream
, i
)) && mc
->deleted
))
394 && (!(flags
& MI_STATECHGONLY
) || (exbits
& MSG_EX_STATECHG
))){
396 * We get here if the message was filtered by a filter that
397 * just changes status bits (it wasn't excluded), and now also
398 * if the message was merely tested for filtering. It has also
399 * not been manually undeleted. If it was manually undeleted, we
400 * don't want to reprocess the filter, undoing the user's
401 * manual undeleting. Of course, a new pine will re check this
402 * message anyway, so the user had better be using this
403 * manual undeleting only to temporarily save him or herself
404 * from an expunge before Saving or printing or something.
405 * Also, we want to still try filtering if the message has at
406 * all been marked deleted, even if the there was any manual
407 * undeleting, since this directly precedes an expunge, we want
408 * to make sure the filter does the right thing before getting
409 * rid of the message forever.
411 exbits
&= ~(MSG_EX_FILTERED
| MSG_EX_TESTED
);
412 msgno_exceptions(stream
, i
, "0", &exbits
, TRUE
);
421 /*----------------------------------------------------------------------
422 Add the given number of raw message numbers to the end of the
425 Accepts: msgs - pointer to message manipulation struct
427 Returns: with fixed up msgno struct
429 Only have to adjust the sort array, as since new mail can't cause
433 msgno_add_raw(MSGNO_S
*msgs
, long int n
)
435 long slop
, islop
, old_total
, old_size
, old_isize
;
441 old_total
= msgs
->max_msgno
;
442 old_size
= msgs
->sort_size
;
443 old_isize
= msgs
->isort_size
;
444 slop
= (msgs
->max_msgno
+ n
+ 1L) % 64;
445 islop
= (msgs
->nmsgs
+ n
+ 1L) % 64;
446 msgs
->sort_size
= (msgs
->max_msgno
+ n
+ 1L) + (64 - slop
);
447 msgs
->isort_size
= (msgs
->nmsgs
+ n
+ 1L) + (64 - islop
);
448 len
= (size_t) msgs
->sort_size
* sizeof(long);
449 ilen
= (size_t) msgs
->isort_size
* sizeof(long);
451 if(old_size
!= msgs
->sort_size
)
452 fs_resize((void **) &(msgs
->sort
), len
);
455 msgs
->sort
= (long *) fs_get(len
);
458 if(old_isize
!= msgs
->isort_size
)
459 fs_resize((void **) &(msgs
->isort
), ilen
);
462 msgs
->isort
= (long *) fs_get(ilen
);
465 msgs
->sort
[++msgs
->max_msgno
] = ++msgs
->nmsgs
;
466 msgs
->isort
[msgs
->nmsgs
] = msgs
->max_msgno
;
469 if(old_total
<= 0L){ /* if no previous messages, */
470 if(!msgs
->select
){ /* select the new message */
472 len
= (size_t) msgs
->sel_size
* sizeof(long);
473 msgs
->select
= (long *) fs_get(len
);
478 msgs
->select
[0] = 1L;
483 /*----------------------------------------------------------------------
484 Remove all knowledge of the given raw message number
486 Accepts: msgs - pointer to message manipulation struct
487 rawno - number to remove
488 Returns: with fixed up msgno struct
490 After removing *all* references, adjust the sort array and
491 various pointers accordingly...
494 msgno_flush_raw(MSGNO_S
*msgs
, long int rawno
)
496 long i
, old_sorted
= 0L;
502 /* blast rawno from sort array */
503 for(i
= 1L; i
<= msgs
->max_msgno
; i
++){
504 if(msgs
->sort
[i
] == rawno
){
509 if(shift
&& i
< msgs
->max_msgno
)
510 msgs
->sort
[i
] = msgs
->sort
[i
+ 1L];
512 if(msgs
->sort
[i
] > rawno
)
516 /*---- now, fixup counts and select array ----*/
517 if(--msgs
->nmsgs
< 0)
521 if(--msgs
->max_msgno
< 0)
522 msgs
->max_msgno
= 0L;
524 msgno_flush_selected(msgs
, old_sorted
);
527 msgno_reset_isort(msgs
);
530 snprintf(b
, sizeof(b
),
531 "isort validity: end of msgno_flush_raw: rawno=%ld\n", rawno
);
536 /*----------------------------------------------------------------------
537 Remove all knowledge of the given selected message number
539 Accepts: msgs - pointer to message manipulation struct
541 Returns: with fixed up selec members in msgno struct
543 Remove reference and fix up selected message numbers beyond
547 msgno_flush_selected(MSGNO_S
*msgs
, long int n
)
552 for(i
= 0L; i
< msgs
->sel_cnt
; i
++){
553 if(!shift
&& (msgs
->select
[i
] == n
))
556 if(shift
&& i
+ 1L < msgs
->sel_cnt
)
557 msgs
->select
[i
] = msgs
->select
[i
+ 1L];
559 if(n
< msgs
->select
[i
] || msgs
->select
[i
] > msgs
->max_msgno
)
560 msgs
->select
[i
] -= 1L;
563 if(shift
&& msgs
->sel_cnt
> 1L)
569 msgno_set_sort(MSGNO_S
*msgs
, SortOrder sort
)
572 if(sort
== SortScore
)
573 scores_are_used(SCOREUSE_INVALID
);
575 msgs
->sort_order
= sort
;
580 /*----------------------------------------------------------------------
581 Test to see if the given message number is in the selected message
584 Accepts: msgs - pointer to message manipulation struct
586 Returns: true if n is in selected array, false otherwise
590 msgno_in_select(MSGNO_S
*msgs
, long int n
)
595 for(i
= 0L; i
< msgs
->sel_cnt
; i
++)
596 if(msgs
->select
[i
] == n
)
604 /*----------------------------------------------------------------------
605 return our index number for the given raw message number
607 Accepts: msgs - pointer to message manipulation struct
608 msgno - number that's important
610 Returns: our index number of given raw message
614 msgno_exceptions(MAILSTREAM
*stream
, long int rawno
, char *part
, int *bits
, int set
)
616 PINELT_S
**peltp
= NULL
;
617 PARTEX_S
**partp
= NULL
;
620 if(!stream
|| rawno
< 1L || rawno
> stream
->nmsgs
)
624 * Get pointer to exceptional part list, and scan down it
625 * for the requested part...
627 if((mc
= mail_elt(stream
, rawno
)) && (*(peltp
= (PINELT_S
**) &mc
->sparep
)))
628 for(partp
= &(*peltp
)->exceptions
; *partp
; partp
= &(*partp
)->next
){
630 if(!strcmp(part
, (*partp
)->partno
)){
633 (*partp
)->handling
= *bits
;
635 *bits
= (*partp
)->handling
;
638 return(TRUE
); /* bingo! */
643 * The caller provided flags, but no part.
644 * We are looking to see if the bits are set in any of the
645 * parts. This doesn't count parts with non-digit partno's (like
646 * scores) because those are used differently.
647 * any of the flags...
649 if((*partp
)->partno
&& *(*partp
)->partno
&&
650 isdigit((unsigned char) *(*partp
)->partno
) &&
651 (*bits
& (*partp
)->handling
) == *bits
)
656 * The caller didn't specify a part, so
657 * they must just be interested in whether
658 * the msg had any exceptions at all...
665 *peltp
= (PINELT_S
*) fs_get(sizeof(PINELT_S
));
666 memset(*peltp
, 0, sizeof(PINELT_S
));
667 partp
= &(*peltp
)->exceptions
;
670 (*partp
) = (PARTEX_S
*) fs_get(sizeof(PARTEX_S
));
671 (*partp
)->partno
= cpystr(part
);
672 (*partp
)->next
= NULL
;
673 (*partp
)->handling
= *bits
;
677 if(bits
) /* init bits */
685 * Checks whether any parts of any of the messages in msgmap are marked
689 msgno_any_deletedparts(MAILSTREAM
*stream
, MSGNO_S
*msgmap
)
696 for(n
= mn_first_cur(msgmap
); n
> 0L; n
= mn_next_cur(msgmap
))
697 if((rawno
= mn_m2raw(msgmap
, n
)) > 0L
698 && stream
&& rawno
<= stream
->nmsgs
699 && (mc
= mail_elt(stream
, rawno
))
700 && (pelt
= (PINELT_S
*) mc
->sparep
))
701 for(partp
= &pelt
->exceptions
; *partp
; partp
= &(*partp
)->next
)
702 if(((*partp
)->handling
& MSG_EX_DELETE
)
704 && *(*partp
)->partno
!= '0'
705 && isdigit((unsigned char) *(*partp
)->partno
))
713 msgno_part_deleted(MAILSTREAM
*stream
, long int rawno
, char *part
)
719 * Is this attachment or any of it's parents in the
720 * MIME structure marked for deletion?
722 for(p
= part
; p
&& *p
; p
= strindex(++p
, '.')){
726 (void) msgno_exceptions(stream
, rawno
, part
, &expbits
, FALSE
);
730 if(expbits
& MSG_EX_DELETE
)
734 /* Finally, check if the whole message body's deleted */
735 return(msgno_exceptions(stream
, rawno
, "", &expbits
, FALSE
)
736 ? (expbits
& MSG_EX_DELETE
) : FALSE
);
742 * Set the score for a message to score, which can be anything including
746 set_msg_score(MAILSTREAM
*stream
, long int rawmsgno
, long int score
)
750 /* scores are between SCORE_MIN and SCORE_MAX, so ok */
751 intscore
= (int) score
;
753 (void) msgno_exceptions(stream
, rawmsgno
, "S", &intscore
, TRUE
);
758 * Returns the score for a message. If that score is undefined the value
759 * returned will be SCORE_UNDEF, so the caller has to be prepared for that.
760 * The caller should calculate the undefined scores before calling this.
763 get_msg_score(MAILSTREAM
*stream
, long int rawmsgno
)
768 if(msgno_exceptions(stream
, rawmsgno
, "S", &s
, FALSE
))
778 clear_msg_score(MAILSTREAM
*stream
, long int rawmsgno
)
783 set_msg_score(stream
, rawmsgno
, SCORE_UNDEF
);
788 * Set all the score values to undefined.
791 clear_folder_scores(MAILSTREAM
*stream
)
798 for(n
= 1L; n
<= stream
->nmsgs
; n
++)
799 clear_msg_score(stream
, n
);
804 * Calculates all of the scores for the searchset and stores them in the
805 * mail elts. Careful, this function uses patterns so if the caller is using
806 * patterns then the caller will probably have to reset the pattern functions.
807 * That is, will have to call first_pattern again with the correct type.
810 * searchset -- calculate scores for this set of messages
811 * no_fetch -- we're in a callback from c-client, don't call c-client
814 * 0 -- error, because of no_fetch
817 calculate_some_scores(MAILSTREAM
*stream
, SEARCHSET
*searchset
, int no_fetch
)
822 long newscore
, addtoscore
, score
;
824 long rflags
= ROLE_SCORE
;
828 HEADER_TOK_S
*hdrtok
;
830 dprint((7, "calculate_some_scores\n"));
832 if(nonempty_patterns(rflags
, &pstate
)){
834 /* calculate scores */
837 /* this calls match_pattern which messes up searched bits */
838 savebits
= (char *)fs_get((stream
->nmsgs
+1) * sizeof(char));
839 for(i
= 1L; i
<= stream
->nmsgs
; i
++)
840 savebits
[i
] = (mc
= mail_elt(stream
, i
)) ? mc
->searched
: 0;
843 * First set all the scores in the searchset to zero so that they
844 * will no longer be undefined.
847 for(s
= searchset
; s
; s
= s
->next
)
848 for(n
= s
->first
; n
<= s
->last
; n
++)
849 set_msg_score(stream
, n
, score
);
851 for(pat
= first_pattern(&pstate
);
853 pat
= next_pattern(&pstate
)){
855 newscore
= pat
->action
->scoreval
;
856 hdrtok
= pat
->action
->scorevalhdrtok
;
859 * This no_fetch probably isn't necessary since
860 * we will actually have fetched this with
861 * the envelope. Just making sure.
868 switch(match_pattern(pat
->patgrp
, stream
, searchset
, NULL
, NULL
,
869 (no_fetch
? MP_IN_CCLIENT_CB
: 0)
870 | (SE_NOSERVER
|SE_NOPREFETCH
))){
872 if(!pat
->action
|| pat
->action
->bogus
)
875 for(s
= searchset
; s
; s
= s
->next
)
876 for(n
= s
->first
; n
<= s
->last
; n
++)
877 if(n
> 0L && stream
&& n
<= stream
->nmsgs
878 && (mc
= mail_elt(stream
, n
)) && mc
->searched
){
879 if((score
= get_msg_score(stream
,n
)) == SCORE_UNDEF
)
883 addtoscore
= scorevalfrommsg(stream
, n
, hdrtok
, no_fetch
);
885 addtoscore
= newscore
;
888 set_msg_score(stream
, n
, score
);
902 for(i
= 1L; i
<= stream
->nmsgs
; i
++)
903 if((mc
= mail_elt(stream
, i
)) != NULL
)
904 mc
->searched
= savebits
[i
];
906 fs_give((void **)&savebits
);
910 * Revert to undefined scores.
913 for(s
= searchset
; s
; s
= s
->next
)
914 for(n
= s
->first
; n
<= s
->last
; n
++)
915 set_msg_score(stream
, n
, score
);
920 return(error
? 0 : 1);
925 free_pine_elt(void **sparep
)
929 peltp
= (PINELT_S
**) sparep
;
932 msgno_free_exceptions(&(*peltp
)->exceptions
);
934 fs_give((void **) &(*peltp
)->pthrd
);
936 if((*peltp
)->firsttext
)
937 fs_give((void **) &(*peltp
)->firsttext
);
940 free_ice(&(*peltp
)->ice
);
942 fs_give((void **) peltp
);