NetBSD/usr.bin/mail/thread.c

1736 lines
37 KiB
C
Raw Normal View History

2012-10-22 02:18:16 +04:00
/* $NetBSD: thread.c,v 1.10 2012/10/21 22:18:16 christos Exp $ */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Anon Ymous.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This module contains the threading and sorting routines.
*/
#ifdef THREAD_SUPPORT
#include <sys/cdefs.h>
#ifndef __lint__
2012-10-22 02:18:16 +04:00
__RCSID("$NetBSD: thread.c,v 1.10 2012/10/21 22:18:16 christos Exp $");
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
#endif /* not __lint__ */
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <util.h>
#include "def.h"
#include "glob.h"
#include "extern.h"
#include "format.h"
#include "thread.h"
struct thread_s {
struct message *t_head; /* head of the thread */
struct message **t_msgtbl; /* message array indexed by msgnum */
int t_msgCount; /* count of messages in thread */
};
#define THREAD_INIT {NULL, NULL, 0}
typedef int state_t;
#define S_STATE_INIT 0
#define S_EXPOSE 1 /* flag to expose the thread */
#define S_RESTRICT 2 /* flag to restrict to tagged messages */
#define S_IS_EXPOSE(a) ((a) & S_EXPOSE)
#define S_IS_RESTRICT(a) ((a) & S_RESTRICT)
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
/* XXX - this isn't really a thread */
static struct thread_s message_array = THREAD_INIT; /* the basic message array */
static struct thread_s current_thread = THREAD_INIT; /* the current thread */
static state_t state = S_STATE_INIT; /* the current state */
/*
* A state hook used by the format module.
*/
PUBLIC int
thread_hidden(void)
{
return !S_IS_EXPOSE(state);
}
/************************************************************************
* Debugging stuff that should evaporate eventually.
*/
#ifdef THREAD_DEBUG
static void
show_msg(struct message *mp)
{
if (mp == NULL)
return;
/*
* Arg! '%p' doesn't like the '0' modifier.
*/
(void)printf("%3d (%p):"
" flink=%p blink=%p clink=%p plink=%p"
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
" depth=%d flags=0x%03x\n",
mp->m_index, mp,
mp->m_flink, mp->m_blink, mp->m_clink, mp->m_plink,
mp->m_depth, mp->m_flag);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
}
#ifndef __lint__
__unused
static void
show_thread(struct message *mp)
{
(void)printf("current_thread.t_head=%p\n", current_thread.t_head);
for (/*EMPTY*/; mp; mp = next_message(mp))
show_msg(mp);
}
#endif
PUBLIC int
thread_showcmd(void *v)
{
int *ip;
(void)printf("current_thread.t_head=%p\n", current_thread.t_head);
for (ip = v; *ip; ip++)
show_msg(get_message(*ip));
return 0;
}
#endif /* THREAD_DEBUG */
/*************************************************************************
* tag/restrict routines
*/
/*
* Return TRUE iff all messages forward or below this one are tagged.
*/
static int
is_tagged_core(struct message *mp)
{
if (S_IS_EXPOSE(state))
return 1;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
for (/*EMPTY*/; mp; mp = mp->m_flink)
if ((mp->m_flag & MTAGGED) == 0 ||
is_tagged_core(mp->m_clink) == 0)
return 0;
return 1;
}
static int
is_tagged(struct message *mp)
{
return mp->m_flag & MTAGGED && is_tagged_core(mp->m_clink);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
}
/************************************************************************
* These are the core routines to access messages via the links used
* everywhere outside this module and fio.c.
*/
static int
has_parent(struct message *mp)
{
return mp->m_plink != NULL &&
mp->m_plink->m_clink != current_thread.t_head;
}
static struct message *
next_message1(struct message *mp)
{
if (mp == NULL)
return NULL;
if (S_IS_EXPOSE(state) == 0)
return mp->m_flink;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (mp->m_clink)
return mp->m_clink;
while (mp->m_flink == NULL && has_parent(mp))
mp = mp->m_plink;
return mp->m_flink;
}
static struct message *
prev_message1(struct message *mp)
{
if (mp == NULL)
return NULL;
if (S_IS_EXPOSE(state) && mp->m_blink == NULL && has_parent(mp))
return mp->m_plink;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
return mp->m_blink;
}
PUBLIC struct message *
next_message(struct message *mp)
{
if (S_IS_RESTRICT(state) == 0)
return next_message1(mp);
while ((mp = next_message1(mp)) != NULL && is_tagged(mp))
continue;
return mp;
}
PUBLIC struct message *
prev_message(struct message *mp)
{
if (S_IS_RESTRICT(state) == 0)
return prev_message1(mp);
while ((mp = prev_message1(mp)) != NULL && is_tagged(mp))
continue;
return mp;
}
static struct message *
first_message(struct message *mp)
{
if (S_IS_RESTRICT(state) && is_tagged(mp))
mp = next_message(mp);
return mp;
}
PUBLIC struct message *
get_message(int msgnum)
{
struct message *mp;
if (msgnum < 1 || msgnum > current_thread.t_msgCount)
return NULL;
mp = current_thread.t_msgtbl[msgnum - 1];
assert(mp->m_index == msgnum);
return mp;
}
PUBLIC int
get_msgnum(struct message *mp)
{
return mp ? mp->m_index : 0;
}
PUBLIC int
get_msgCount(void)
{
return current_thread.t_msgCount;
}
PUBLIC int
get_abs_msgCount(void)
{
return message_array.t_msgCount;
}
PUBLIC struct message *
get_abs_message(int msgnum)
{
if (msgnum < 1 || msgnum > message_array.t_msgCount)
return NULL;
return &message_array.t_head[msgnum - 1];
}
PUBLIC struct message *
next_abs_message(struct message *mp)
{
int i;
i = (int)(mp - message_array.t_head);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (i < 0 || i + 1 >= message_array.t_msgCount)
return NULL;
return &message_array.t_head[i + 1];
}
/************************************************************************/
/*
* routines to handle the recursion of commands.
*/
PUBLIC int
do_recursion(void)
{
return S_IS_EXPOSE(state) == 0 && value(ENAME_RECURSIVE_CMDS) != NULL;
}
static int
thread_recursion_flist(struct message *mp, int (*fn)(struct message *, void *), void *args)
{
int retval;
for (/*EMPTY*/; mp; mp = mp->m_flink) {
if (S_IS_RESTRICT(state) && is_tagged(mp))
continue;
if ((retval = fn(mp, args)) != 0 ||
(retval = thread_recursion_flist(mp->m_clink, fn, args)) != 0)
return retval;
}
return 0;
}
PUBLIC int
thread_recursion(struct message *mp, int (*fn)(struct message *, void *), void *args)
{
int retval;
assert(mp != NULL);
if ((retval = fn(mp, args)) != 0)
return retval;
if (do_recursion() &&
(retval = thread_recursion_flist(mp->m_clink, fn, args)) != 0)
return retval;
return 0;
}
/************************************************************************
* A hook for sfmtfield() in format.c. It is the only place outside
* this module that the m_depth is known.
*/
PUBLIC int
thread_depth(void)
{
return current_thread.t_head ? current_thread.t_head->m_depth : 0;
}
/************************************************************************/
static int
reindex_core(struct message *mp)
{
int i;
assert(mp->m_blink == NULL);
i = 0;
for (mp = first_message(mp); mp; mp = mp->m_flink) {
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
assert(mp->m_flink == NULL || mp == mp->m_flink->m_blink);
assert(mp->m_blink == NULL || mp == mp->m_blink->m_flink);
assert(mp->m_size != 0);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (S_IS_RESTRICT(state) == 0 || !is_tagged(mp))
mp->m_index = ++i;
if (mp->m_clink)
(void)reindex_core(mp->m_clink);
}
return i;
}
static void
reindex(struct thread_s *tp)
{
struct message *mp;
int i;
assert(tp != NULL);
if ((mp = tp->t_head) == NULL || mp->m_size == 0)
return;
assert(mp->m_blink == NULL);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (S_IS_EXPOSE(state) == 0) {
/*
* We special case this so that all the hidden
* sub-threads get indexed, not just the current one.
*/
i = reindex_core(tp->t_head);
}
else {
i = 0;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
for (mp = first_message(tp->t_head); mp; mp = next_message(mp))
mp->m_index = ++i;
}
assert(i <= message_array.t_msgCount);
tp->t_msgCount = i;
i = 0;
for (mp = first_message(tp->t_head); mp; mp = next_message(mp))
tp->t_msgtbl[i++] = mp;
}
static void
redepth_core(struct message *mp, int depth, struct message *parent)
{
assert(mp->m_blink == NULL);
assert((parent == NULL && depth == 0) ||
(parent != NULL && depth != 0 && depth == parent->m_depth + 1));
for (/*EMPTY*/; mp; mp = mp->m_flink) {
assert(mp->m_plink == parent);
assert(mp->m_flink == NULL || mp == mp->m_flink->m_blink);
assert(mp->m_blink == NULL || mp == mp->m_blink->m_flink);
assert(mp->m_size != 0);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
mp->m_depth = depth;
if (mp->m_clink)
redepth_core(mp->m_clink, depth + 1, mp);
}
}
static void
redepth(struct thread_s *thread)
{
int depth;
struct message *mp;
assert(thread != NULL);
if ((mp = thread->t_head) == NULL || mp->m_size == 0)
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
return;
depth = mp->m_plink ? mp->m_plink->m_depth + 1 : 0;
#ifndef NDEBUG /* a sanity check if asserts are active */
{
struct message *tp;
int i;
i = 0;
for (tp = mp->m_plink; tp; tp = tp->m_plink)
i++;
assert(i == depth);
}
#endif
redepth_core(mp, depth, mp->m_plink);
}
/************************************************************************
* To be called after reallocating the main message list. It is here
* as it needs access to current_thread.t_head.
*/
PUBLIC void
thread_fix_old_links(struct message *nmessage, struct message *message, int omsgCount)
{
int i;
if (nmessage == message)
return;
#ifndef NDEBUG
message_array.t_head = nmessage; /* for assert check in thread_fix_new_links */
#endif
# define FIX_LINK(p) do {\
if (p)\
p = nmessage + (p - message);\
} while (/*CONSTCOND*/0)
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
FIX_LINK(current_thread.t_head);
for (i = 0; i < omsgCount; i++) {
FIX_LINK(nmessage[i].m_blink);
FIX_LINK(nmessage[i].m_flink);
FIX_LINK(nmessage[i].m_clink);
FIX_LINK(nmessage[i].m_plink);
}
for (i = 0; i < current_thread.t_msgCount; i++)
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
FIX_LINK(current_thread.t_msgtbl[i]);
# undef FIX_LINK
}
static void
thread_init(struct thread_s *tp, struct message *mp, int msgCount)
{
int i;
if (tp->t_msgtbl == NULL || msgCount > tp->t_msgCount) {
if (tp->t_msgtbl)
free(tp->t_msgtbl);
tp->t_msgtbl = ecalloc((size_t)msgCount, sizeof(tp->t_msgtbl[0]));
}
tp->t_head = mp;
tp->t_msgCount = msgCount;
for (i = 0; i < msgCount; i++)
tp->t_msgtbl[i] = &mp[i];
}
/*
* To be called after reading in the new message structures.
* It is here as it needs access to current_thread.t_head.
*/
PUBLIC void
thread_fix_new_links(struct message *message, int omsgCount, int msgCount)
{
int i;
struct message *lastmp;
/* This should only be called at the top level if omsgCount != 0! */
assert(omsgCount == 0 || message->m_plink == NULL);
assert(omsgCount == 0 || message_array.t_msgCount == omsgCount);
assert(message_array.t_head == message);
message_array.t_head = message;
message_array.t_msgCount = msgCount;
assert(message_array.t_msgtbl == NULL); /* never used */
lastmp = NULL;
if (omsgCount) {
/*
* Find the end of the toplevel thread.
*/
for (i = 0; i < omsgCount; i++) {
if (message_array.t_head[i].m_depth == 0 &&
message_array.t_head[i].m_flink == NULL) {
lastmp = &message_array.t_head[i];
break;
}
}
#ifndef NDEBUG
/*
* lastmp better be unique!!!
*/
for (i++; i < omsgCount; i++)
assert(message_array.t_head[i].m_depth != 0 ||
message_array.t_head[i].m_flink != NULL);
assert(lastmp != NULL);
#endif /* NDEBUG */
}
/*
* Link and index the new messages linearly at depth 0.
*/
for (i = omsgCount; i < msgCount; i++) {
message[i].m_index = i + 1;
message[i].m_depth = 0;
message[i].m_blink = lastmp;
message[i].m_flink = NULL;
message[i].m_clink = NULL;
message[i].m_plink = NULL;
if (lastmp)
lastmp->m_flink = &message[i];
lastmp = &message[i];
}
/*
* Make sure the current thread is setup correctly.
*/
if (omsgCount == 0) {
thread_init(&current_thread, message, msgCount);
}
else {
/*
* Make sure current_thread.t_msgtbl is always large
* enough.
*/
current_thread.t_msgtbl =
erealloc(current_thread.t_msgtbl,
msgCount * sizeof(*current_thread.t_msgtbl));
assert(current_thread.t_head != NULL);
if (current_thread.t_head->m_depth == 0)
reindex(&current_thread);
}
}
/************************************************************************/
/*
* All state changes should go through here!!!
*/
/*
* NOTE: It is the caller's responsibility to ensure that the "dot"
* will be valid after a state change. For example, when changing
* from exposed to hidden threads, it is necessary to move the dot to
* the head of the thread or it will not be seen. Use thread_top()
* for this. Likewise, use first_visible_message() to locate the
* first visible message after a state change.
*/
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
static state_t
set_state(int and_bits, int xor_bits)
{
state_t old_state;
old_state = state;
state &= and_bits;
state ^= xor_bits;
reindex(&current_thread);
redepth(&current_thread);
return old_state;
}
static struct message *
first_visible_message(struct message *mp)
{
struct message *oldmp;
if (mp == NULL)
mp = current_thread.t_head;
oldmp = mp;
if ((S_IS_RESTRICT(state) && is_tagged(mp)) || mp->m_flag & MDELETED)
mp = next_message(mp);
if (mp == NULL) {
mp = oldmp;
if ((S_IS_RESTRICT(state) && is_tagged(mp)) || mp->m_flag & MDELETED)
mp = prev_message(mp);
}
if (mp == NULL)
mp = current_thread.t_head;
return mp;
}
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
static void
restore_state(state_t new_state)
{
state = new_state;
reindex(&current_thread);
redepth(&current_thread);
dot = first_visible_message(dot);
}
static struct message *
thread_top(struct message *mp)
{
while (mp && mp->m_plink) {
if (mp->m_plink->m_clink == current_thread.t_head)
break;
mp = mp->m_plink;
}
return mp;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
}
/************************************************************************/
/*
* Possibly show the message list.
*/
static void
thread_announce(void *v)
{
int vec[2];
if (v == NULL) /* check this here to avoid it before each call */
return;
if (dot == NULL) {
(void)printf("No applicable messages\n");
return;
}
vec[0] = get_msgnum(dot);
vec[1] = 0;
if (get_msgCount() > 0 && value(ENAME_NOHEADER) == NULL)
(void)headers(vec);
sawcom = 0; /* so next will print the first message */
}
/************************************************************************/
/*
* Flatten out the portion of the thread starting with the given
* message.
*/
static void
flattencmd_core(struct message *mp)
{
struct message **marray;
size_t mcount;
struct message *tp;
struct message *nextmp;
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (mp == NULL)
return;
mcount = 1;
for (tp = next_message(mp); tp && tp->m_depth > mp->m_depth; tp = next_message(tp))
mcount++;
if (tp && tp->m_depth < mp->m_depth)
nextmp = NULL;
else
nextmp = tp;
if (mcount == 1)
return;
marray = csalloc(mcount, sizeof(*marray));
tp = mp;
for (i = 0; i < mcount; i++) {
marray[i] = tp;
tp = next_message(tp);
}
mp->m_clink = NULL;
for (i = 1; i < mcount; i++) {
marray[i]->m_depth = mp->m_depth;
marray[i]->m_plink = mp->m_plink;
marray[i]->m_clink = NULL;
marray[i]->m_blink = marray[i - 1];
marray[i - 1]->m_flink = marray[i];
}
marray[i - 1]->m_flink = nextmp;
if (nextmp)
nextmp->m_blink = marray[i - 1];
}
/*
* Flatten out all thread parts given in the message list, or the
* current thread, if none given.
*/
PUBLIC int
flattencmd(void *v)
{
int *msgvec;
int *ip;
msgvec = v;
if (*msgvec) { /* a message was supplied */
for (ip = msgvec; *ip; ip++) {
struct message *mp;
mp = get_message(*ip);
if (mp != NULL)
flattencmd_core(mp);
}
}
else { /* no message given - flatten current thread */
struct message *mp;
for (mp = first_message(current_thread.t_head);
mp; mp = next_message(mp))
flattencmd_core(mp);
}
redepth(&current_thread);
thread_announce(v);
return 0;
}
/************************************************************************/
/*
* The basic sort structure. For each message the index and key
* fields are set. The key field is used for the basic sort and the
* index is used to ensure that the order from the current thread is
* maintained when the key compare is equal.
*/
struct key_sort_s {
struct message *mp; /* the message the following refer to */
union {
char *str; /* string sort key (typically a field or address) */
long lines; /* a long sort key (typically a message line count) */
off_t size; /* a size sort key (typically the message size) */
time_t time; /* a time sort key (typically from date or headline) */
} key;
int index; /* index from of the current thread before sorting */
/* XXX - do we really want index? It is always set to mp->m_index */
};
/*
* This is the compare function obtained from the key_tbl[]. It is
* used by thread_array() to identify the end of the thread and by
* qsort_cmpfn() to do the basic sort.
*/
static struct {
int inv;
int (*fn)(const void *, const void *);
} cmp;
/*
* The routine passed to qsort. Note that cmpfn must be set first!
*/
static int
qsort_cmpfn(const void *left, const void *right)
{
int delta;
const struct key_sort_s *lp = left;
const struct key_sort_s *rp = right;
delta = cmp.fn(left, right);
return delta ? cmp.inv ? - delta : delta : lp->index - rp->index;
}
static void
link_array(struct key_sort_s *marray, size_t mcount)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
struct message *lastmp;
lastmp = NULL;
for (i = 0; i < mcount; i++) {
From Anon Ymous: - Remove all longjmp(3) calls from signal handlers. Instead, we post to an internal signal queue and check that periodically. All signal related code is now in sig.c, except for the SIGCHLD handler which remains in popen.c as it is intimately tied to routines there. - Handle SIGPIPE in type1() regardless of mime support, or else the handler in execute() will prevent our error code from being returned resulting in 'sawcom' not being set on the first command as it should. This only affected the initial behavior of the "next" command without mime support. - Add the 'T' flag to many commands in cmdtab.c that should not look like the first command. E.g., start mail on a mailbox with multiple messages, run "set foo", then "next", and watch the second message get displayed rather than the first as is the case without the first "set" command. - Add file descriptor and file handle leak detection. Enabled by DEBUG_FILE_LEAK. This will likely disappear in the future. - Fix a long standing (since import in 1993) longjmp() bug in edstop(): the jmpbuf was invalid when quit() is called at the end of main. - Fix a long standing bug (since import in 1993) in snarf() where it didn't strip whitespace correctly if the line consisted only of whitespace. - Lint cleanup. - New Feature: "Header" command. This allows miscellaneous header fields to be added to the header, e.g., "X-Organization:" or "Reply-To:" fields. - New Feature: "page-also" variable. This allows the specification of additional commands to page. It is more flexible than "crt". - Document the "pager-off" variable: if set, it disables paging entirely.
2009-04-10 17:08:24 +04:00
marray[i].mp->m_index = (int)i + 1;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
marray[i].mp->m_blink = lastmp;
marray[i].mp->m_flink = NULL;
if (lastmp)
lastmp->m_flink = marray[i].mp;
lastmp = marray[i].mp;
}
if (current_thread.t_head->m_plink)
current_thread.t_head->m_plink->m_clink = marray[0].mp;
current_thread.t_head = marray[0].mp;
}
static void
2009-01-18 04:29:57 +03:00
cut_array(struct key_sort_s *marray, size_t beg, size_t end)
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (beg + 1 < end) {
assert(marray[beg].mp->m_clink == NULL);
marray[beg].mp->m_clink = marray[beg + 1].mp;
marray[beg + 1].mp->m_blink = NULL;
marray[beg].mp->m_flink = marray[end].mp;
if (marray[end].mp)
marray[end].mp->m_blink = marray[beg].mp;
marray[end - 1].mp->m_flink = NULL;
for (i = beg + 1; i < end; i++)
marray[i].mp->m_plink = marray[beg].mp;
}
}
static void
thread_array(struct key_sort_s *marray, size_t mcount, int cutit)
{
struct message *parent;
parent = marray[0].mp->m_plink;
qsort(marray, mcount, sizeof(*marray), qsort_cmpfn);
link_array(marray, mcount);
if (cutit) {
2009-01-18 04:29:57 +03:00
size_t i, j;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
/*
* Flatten out the array.
*/
for (i = 0; i < mcount; i++) {
marray[i].mp->m_plink = parent;
marray[i].mp->m_clink = NULL;
}
/*
* Now chop it up. There is really only one level here.
*/
i = 0;
for (j = 1; j < mcount; j++) {
if (cmp.fn(&marray[i], &marray[j]) != 0) {
cut_array(marray, i, j);
i = j;
}
}
cut_array(marray, i, j);
}
}
/************************************************************************/
/*
* thread_on_reference() is the core reference threading routine. It
* is not a command itself by called by threadcmd().
*/
static void
adopt_child(struct message *parent, struct message *child)
{
/*
* Unhook the child from its current location.
*/
if (child->m_blink != NULL) {
child->m_blink->m_flink = child->m_flink;
}
if (child->m_flink != NULL) {
child->m_flink->m_blink = child->m_blink;
}
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
/*
* Link the child to the parent.
*/
if (parent->m_clink == NULL) { /* parent has no child */
parent->m_clink = child;
child->m_blink = NULL;
}
else { /* add message to end of parent's child's flist */
struct message *t;
for (t = parent->m_clink; t && t->m_flink; t = t->m_flink)
continue;
t->m_flink = child;
child->m_blink = t;
}
child->m_flink = NULL;
child->m_plink = parent;
}
/*
* Get the parent ID for a message (if there is one).
*
* See RFC 2822, sec 3.6.4.
*
* Many mailers seem to screw up the In-Reply-To: and/or
* References: fields, generally by omitting one or both.
*
* We give preference to the "References" field. If it does
* not exist, try the "In-Reply-To" field. If neither exist,
* then the message is either not a reply or someone isn't
* adding the necessary fields, so skip it.
*/
static char *
get_parent_id(struct message *mp)
{
struct name *refs;
if ((refs = extract(hfield("references", mp), 0)) != NULL) {
char *id;
while (refs->n_flink)
refs = refs->n_flink;
id = skin(refs->n_name);
if (*id != '\0')
return id;
}
return skin(hfield("in-reply-to", mp));
}
/*
* Thread on the "In-Reply-To" and "Reference" fields. This is the
* normal way to thread.
*/
static void
thread_on_reference(struct message *mp)
{
struct {
struct message *mp;
char *message_id;
char *parent_id;
} *marray;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
struct message *parent;
state_t oldstate;
2009-01-18 04:29:57 +03:00
size_t mcount, i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
assert(mp == current_thread.t_head);
oldstate = set_state(~(S_RESTRICT | S_EXPOSE), S_EXPOSE); /* restrict off, expose on */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
mcount = get_msgCount();
if (mcount < 2) /* it's hard to thread so few messages! */
goto done;
marray = csalloc(mcount + 1, sizeof(*marray));
/*
* Load up the array (skin where necessary).
*
* With a 40K message file, most of the time is spent here,
* not in the search loop below.
*/
for (i = 0; i < mcount; i++) {
marray[i].mp = mp;
marray[i].message_id = skin(hfield("message-id", mp));
marray[i].parent_id = get_parent_id(mp);
mp = next_message(mp);
}
/*
* Save the old parent.
*/
parent = marray[0].mp->m_plink;
/*
* flatten the array.
*/
marray[0].mp->m_clink = NULL;
for (i = 1; i < mcount; i++) {
marray[i].mp->m_depth = marray[0].mp->m_depth;
marray[i].mp->m_plink = marray[0].mp->m_plink;
marray[i].mp->m_clink = NULL;
marray[i].mp->m_blink = marray[i - 1].mp;
marray[i - 1].mp->m_flink = marray[i].mp;
}
marray[i - 1].mp->m_flink = NULL;
/*
* Walk the array hooking up the replies with their parents.
*/
for (i = 0; i < mcount; i++) {
struct message *child;
char *parent_id;
2009-01-18 04:29:57 +03:00
size_t j;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if ((parent_id = marray[i].parent_id) == NULL)
continue;
child = marray[i].mp;
/*
* Look for the parent message and link this one in
* appropriately.
*
* XXX - This will not scale nicely, though it does
* not appear to be the dominant loop even with 40K
* messages. If this becomes a problem, implement a
* binary search.
*/
for (j = 0; j < mcount; j++) {
/* message_id will be NULL on mbox files */
2012-10-22 02:18:16 +04:00
if (marray[j].message_id == NULL)
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
continue;
if (equal(marray[j].message_id, parent_id)) {
/*
* The child is at the top level. If
* it is being adopted and it was top
* left (current_thread.t_head), then
* its right sibling is the new top
* left (current_thread.t_head).
*/
if (current_thread.t_head == child) {
current_thread.t_head = child->m_flink;
assert(current_thread.t_head != NULL);
}
adopt_child(marray[j].mp, child);
break;
}
}
}
if (parent)
parent->m_clink = current_thread.t_head;
/*
* If the old state is not exposed, reset the dot to the head
* of the thread it lived in, so it will be in a valid spot
* when things are re-hidden.
*/
if (!S_IS_EXPOSE(oldstate))
dot = thread_top(dot);
done:
restore_state(oldstate);
}
/************************************************************************/
/*
* Tagging commands.
*/
static int
tag1(int *msgvec, int and_bits, int xor_bits)
{
int *ip;
for (ip = msgvec; *ip != 0; ip++)
(void)set_m_flag(*ip, and_bits, xor_bits);
reindex(&current_thread);
/* thread_announce(v); */
return 0;
}
/*
* Tag the current message dot or a message list.
*/
PUBLIC int
tagcmd(void *v)
{
return tag1(v, ~MTAGGED, MTAGGED);
}
/*
* Untag the current message dot or a message list.
*/
PUBLIC int
untagcmd(void *v)
{
return tag1(v, ~MTAGGED, 0);
}
/*
* Invert all tags in the message list.
*/
PUBLIC int
invtagscmd(void *v)
{
return tag1(v, ~0, MTAGGED);
}
/*
* Tag all messages below the current dot or below a specified
* message.
*/
PUBLIC int
tagbelowcmd(void *v)
{
int *msgvec;
struct message *mp;
state_t oldstate;
int depth;
msgvec = v;
oldstate = set_state(~(S_RESTRICT | S_EXPOSE), S_EXPOSE); /* restrict off, expose on */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
mp = get_message(*msgvec);
if (mp) {
depth = mp->m_depth;
for (mp = first_message(current_thread.t_head); mp; mp = next_message(mp))
if (mp->m_depth > depth) {
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
mp->m_flag |= MTAGGED;
touch(mp);
}
}
/* dot is OK */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
restore_state(oldstate);
/* thread_announce(v); */
return 0;
}
/*
* Do not display the tagged messages.
*/
PUBLIC int
hidetagscmd(void *v)
{
(void)set_state(~S_RESTRICT, S_RESTRICT); /* restrict on */
dot = first_visible_message(dot);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
thread_announce(v);
return 0;
}
/*
* Display the tagged messages.
*/
PUBLIC int
showtagscmd(void *v)
{
(void)set_state(~S_RESTRICT, 0); /* restrict off */
dot = first_visible_message(dot);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
thread_announce(v);
return 0;
}
/************************************************************************/
/*
* Basic threading commands.
*/
/*
* Show the threads.
*/
PUBLIC int
exposecmd(void *v)
{
(void)set_state(~S_EXPOSE, S_EXPOSE); /* expose on */
dot = first_visible_message(dot);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
thread_announce(v);
return 0;
}
/*
* Hide the threads.
*/
PUBLIC int
hidecmd(void *v)
{
dot = thread_top(dot);
(void)set_state(~S_EXPOSE, 0); /* expose off */
dot = first_visible_message(dot);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
thread_announce(v);
return 0;
}
/*
* Up one level in the thread tree. Go up multiple levels if given an
* argument.
*/
PUBLIC int
upcmd(void *v)
{
char *str;
int upcnt;
int upone;
str = v;
str = skip_WSP(str);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (*str == '\0')
upcnt = 1;
else
upcnt = atoi(str);
if (upcnt < 1) {
(void)printf("Sorry, argument must be > 0.\n");
return 0;
}
if (dot == NULL) {
(void)printf("No applicable messages\n");
return 0;
}
if (dot->m_plink == NULL) {
(void)printf("top thread\n");
return 0;
}
upone = 0;
while (upcnt-- > 0) {
struct message *parent;
parent = current_thread.t_head->m_plink;
if (parent == NULL) {
(void)printf("top thread\n");
break;
}
else {
struct message *mp;
assert(current_thread.t_head->m_depth > 0);
for (mp = parent; mp && mp->m_blink; mp = mp->m_blink)
continue;
current_thread.t_head = mp;
dot = parent;
upone = 1;
}
}
if (upone) {
reindex(&current_thread);
thread_announce(v);
}
return 0;
}
/*
* Go down one level in the thread tree from the current dot or a
* given message number if given.
*/
PUBLIC int
downcmd(void *v)
{
struct message *child;
struct message *mp;
int *msgvec = v;
if ((mp = get_message(*msgvec)) == NULL ||
(child = mp->m_clink) == NULL)
(void)printf("no sub-thread\n");
else {
current_thread.t_head = child;
dot = child;
reindex(&current_thread);
thread_announce(v);
}
return 0;
}
/*
* Set the current thread level to the current dot or to the message
* if given.
*/
PUBLIC int
tsetcmd(void *v)
{
struct message *mp;
int *msgvec = v;
if ((mp = get_message(*msgvec)) == NULL)
(void)printf("invalid message\n");
else {
for (/*EMPTY*/; mp->m_blink; mp = mp->m_blink)
continue;
current_thread.t_head = mp;
reindex(&current_thread);
thread_announce(v);
}
return 0;
}
/*
* Reverse the current thread order. If threaded, it only operates on
* the heads.
*/
static void
reversecmd_core(struct thread_s *tp)
{
struct message *thread_start;
struct message *mp;
struct message *lastmp;
struct message *old_flink;
thread_start = tp->t_head;
assert(thread_start->m_blink == NULL);
lastmp = NULL;
for (mp = thread_start; mp; mp = old_flink) {
old_flink = mp->m_flink;
mp->m_flink = mp->m_blink;
mp->m_blink = old_flink;
lastmp = mp;
}
if (thread_start->m_plink)
thread_start->m_plink->m_clink = lastmp;
current_thread.t_head = lastmp;
reindex(tp);
}
PUBLIC int
reversecmd(void *v)
{
reversecmd_core(&current_thread);
thread_announce(v);
return 0;
}
/*
* Get threading and sorting modifiers.
*/
#define MF_IGNCASE 1 /* ignore case when sorting */
#define MF_REVERSE 2 /* reverse sort direction */
#define MF_SKIN 4 /* "skin" the field to remove comments */
static int
get_modifiers(char **str)
{
int modflags;
char *p;
modflags = 0;
for (p = *str; p && *p; p++) {
switch (*p) {
case '!':
modflags |= MF_REVERSE;
break;
case '^':
modflags |= MF_IGNCASE;
break;
case '-':
modflags |= MF_SKIN;
break;
case ' ':
case '\t':
break;
default:
goto done;
}
}
done:
*str = p;
return modflags;
}
/************************************************************************/
/*
* The key_sort_s compare routines.
*/
static int
keystrcmp(const void *left, const void *right)
{
const struct key_sort_s *lp = left;
const struct key_sort_s *rp = right;
lp = left;
rp = right;
if (rp->key.str == NULL && lp->key.str == NULL)
return 0;
else if (rp->key.str == NULL)
return -1;
else if (lp->key.str == NULL)
return 1;
else
return strcmp(lp->key.str, rp->key.str);
}
static int
keystrcasecmp(const void *left, const void *right)
{
const struct key_sort_s *lp = left;
const struct key_sort_s *rp = right;
if (rp->key.str == NULL && lp->key.str == NULL)
return 0;
else if (rp->key.str == NULL)
return -1;
else if (lp->key.str == NULL)
return 1;
else
return strcasecmp(lp->key.str, rp->key.str);
}
static int
keylongcmp(const void *left, const void *right)
{
const struct key_sort_s *lp = left;
const struct key_sort_s *rp = right;
if (lp->key.lines > rp->key.lines)
return 1;
if (lp->key.lines < rp->key.lines)
return -1;
return 0;
}
static int
keyoffcmp(const void *left, const void *right)
{
const struct key_sort_s *lp = left;
const struct key_sort_s *rp = right;
if (lp->key.size > rp->key.size)
return 1;
if (lp->key.size < rp->key.size)
return -1;
return 0;
}
static int
keytimecmp(const void *left, const void *right)
{
double delta;
const struct key_sort_s *lp = left;
const struct key_sort_s *rp = right;
delta = difftime(lp->key.time, rp->key.time);
if (delta > 0)
return 1;
if (delta < 0)
return -1;
return 0;
}
/************************************************************************
* key_sort_s loading routines.
*/
static void
field_load(struct key_sort_s *marray, size_t mcount, struct message *mp,
const char *key, int skin_it)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
for (i = 0; i < mcount; i++) {
marray[i].mp = mp;
marray[i].key.str =
skin_it ? skin(hfield(key, mp)) : hfield(key, mp);
marray[i].index = mp->m_index;
mp = next_message(mp);
}
}
static void
subj_load(struct key_sort_s *marray, size_t mcount, struct message *mp,
const char *key __unused, int flags __unused)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
#ifdef __lint__
flags = flags;
key = key;
#endif
for (i = 0; i < mcount; i++) {
char *subj = hfield(key, mp);
while (strncasecmp(subj, "Re:", 3) == 0)
subj = skip_WSP(subj + 3);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
marray[i].mp = mp;
marray[i].key.str = subj;
marray[i].index = mp->m_index;
mp = next_message(mp);
}
}
static void
lines_load(struct key_sort_s *marray, size_t mcount, struct message *mp,
const char *key __unused, int flags)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
int use_blines;
int use_hlines;
#ifdef __lint__
key = key;
#endif
#define HLINES 1
#define BLINES 2
#define TLINES 3
use_hlines = flags == HLINES;
use_blines = flags == BLINES;
for (i = 0; i < mcount; i++) {
marray[i].mp = mp;
marray[i].key.lines = use_hlines ? mp->m_lines - mp->m_blines :
use_blines ? mp->m_blines : mp->m_lines;
marray[i].index = mp->m_index;
mp = next_message(mp);
}
}
static void
size_load(struct key_sort_s *marray, size_t mcount, struct message *mp,
const char *key __unused, int flags __unused)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
#ifdef __lint__
flags = flags;
key = key;
#endif
for (i = 0; i < mcount; i++) {
marray[i].mp = mp;
marray[i].key.size = mp->m_size;
marray[i].index = mp->m_index;
mp = next_message(mp);
}
}
static void __unused
date_load(struct key_sort_s *marray, size_t mcount, struct message *mp,
const char *key __unused, int flags)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
int use_hl_date;
int zero_hour_min_sec;
#ifdef __lint__
key = key;
#endif
#define RDAY 1
#define SDAY 2
#define RDATE 3
#define SDATE 4
use_hl_date = (flags == RDAY || flags == RDATE);
zero_hour_min_sec = (flags == RDAY || flags == SDAY);
for (i = 0; i < mcount; i++) {
struct tm tm;
(void)dateof(&tm, mp, use_hl_date);
if (zero_hour_min_sec) {
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
}
marray[i].mp = mp;
marray[i].key.time = mktime(&tm);
marray[i].index = mp->m_index;
mp = next_message(mp);
}
}
static void
from_load(struct key_sort_s *marray, size_t mcount, struct message *mp,
const char *key __unused, int flags __unused)
{
2009-01-18 04:29:57 +03:00
size_t i;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
#ifdef __lint__
flags = flags;
key = key;
#endif
for (i = 0; i < mcount; i++) {
marray[i].mp = mp;
marray[i].key.str = nameof(mp, 0);
marray[i].index = mp->m_index;
mp = next_message(mp);
}
}
/************************************************************************
* The master table that controls all sorting and threading.
*/
static const struct key_tbl_s {
const char *key;
void (*loadfn)(struct key_sort_s *, size_t, struct message *, const char *, int);
int flags;
int (*cmpfn)(const void*, const void*);
int (*casecmpfn)(const void*, const void*);
} key_tbl[] = {
{"blines", lines_load, BLINES, keylongcmp, keylongcmp},
{"hlines", lines_load, HLINES, keylongcmp, keylongcmp},
{"tlines", lines_load, TLINES, keylongcmp, keylongcmp},
{"size", size_load, 0, keyoffcmp, keyoffcmp},
{"sday", date_load, SDAY, keytimecmp, keytimecmp},
{"rday", date_load, RDAY, keytimecmp, keytimecmp},
{"sdate", date_load, SDATE, keytimecmp, keytimecmp},
{"rdate", date_load, RDATE, keytimecmp, keytimecmp},
{"from", from_load, 0, keystrcasecmp, keystrcasecmp},
{"subject", subj_load, 0, keystrcmp, keystrcasecmp},
{NULL, field_load, 0, keystrcmp, keystrcasecmp},
};
#ifdef USE_EDITLINE
/*
* This is for use in complete.c to get the list of threading key
* names without exposing the key_tbl[]. The first name is returned
* if called with a pointer to a NULL pointer. Subsequent calls with
* the same cookie give successive names. A NULL return indicates the
* end of the list.
*/
PUBLIC const char *
thread_next_key_name(const void **cookie)
{
const struct key_tbl_s *kp;
kp = *cookie;
if (kp == NULL)
kp = key_tbl;
*cookie = kp->key ? &kp[1] : NULL;
return kp->key;
}
#endif /* USE_EDITLINE */
static const struct key_tbl_s *
get_key(const char *key)
{
const struct key_tbl_s *kp;
for (kp = key_tbl; kp->key != NULL; kp++)
if (strcmp(kp->key, key) == 0)
return kp;
return kp;
}
static int (*
get_cmpfn(const struct key_tbl_s *kp, int ignorecase)
)(const void*, const void*)
{
if (ignorecase)
return kp->casecmpfn;
else
return kp->cmpfn;
}
static void
thread_current_on(char *str, int modflags, int cutit)
{
const struct key_tbl_s *kp;
struct key_sort_s *marray;
size_t mcount;
state_t oldstate;
oldstate = set_state(~(S_RESTRICT | S_EXPOSE), cutit ? S_EXPOSE : 0);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
kp = get_key(str);
mcount = get_msgCount();
marray = csalloc(mcount + 1, sizeof(*marray));
kp->loadfn(marray, mcount, current_thread.t_head, str,
kp->flags ? kp->flags : modflags & MF_SKIN);
cmp.fn = get_cmpfn(kp, modflags & MF_IGNCASE);
cmp.inv = modflags & MF_REVERSE;
thread_array(marray, mcount, cutit);
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (!S_IS_EXPOSE(oldstate))
dot = thread_top(dot);
restore_state(oldstate);
}
/*
* The thread command. Thread the current thread on its references or
* on a specified field.
*/
PUBLIC int
threadcmd(void *v)
{
char *str;
str = v;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
if (*str == '\0')
thread_on_reference(current_thread.t_head);
else {
int modflags;
modflags = get_modifiers(&str);
thread_current_on(str, modflags, 1);
}
thread_announce(v);
return 0;
}
/*
* Remove all threading information, reverting to the startup state.
*/
PUBLIC int
unthreadcmd(void *v)
{
thread_fix_new_links(message_array.t_head, 0, message_array.t_msgCount);
thread_announce(v);
return 0;
}
/*
* The sort command.
*/
PUBLIC int
sortcmd(void *v)
{
int modflags;
char *str;
str = v;
modflags = get_modifiers(&str);
if (*str != '\0')
thread_current_on(str, modflags, 0);
else {
if (modflags & MF_REVERSE)
reversecmd_core(&current_thread);
else {
(void)printf("sort on what?\n");
return 0;
}
}
thread_announce(v);
return 0;
}
/*
* Delete duplicate messages (based on their "Message-Id" field).
*/
/*ARGSUSED*/
PUBLIC int
deldupscmd(void *v __unused)
{
struct message *mp;
int depth;
state_t oldstate;
oldstate = set_state(~(S_RESTRICT | S_EXPOSE), S_EXPOSE); /* restrict off, expose on */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
thread_current_on(__UNCONST("Message-Id"), 0, 1);
reindex(&current_thread);
redepth(&current_thread);
depth = current_thread.t_head->m_depth;
for (mp = first_message(current_thread.t_head); mp; mp = next_message(mp)) {
if (mp->m_depth > depth) {
mp->m_flag &= ~(MPRESERVE | MSAVED | MBOX);
mp->m_flag |= MDELETED | MTOUCH;
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
touch(mp);
}
}
dot = thread_top(dot); /* do this irrespective of the oldstate */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
restore_state(oldstate);
/* thread_announce(v); */
From Anon Ymous: 1) Statification of modules. 2) Implement the 'detach' and 'Detach' commands for extracting mime parts from messages. 3) Teach mail to output "In-Reply-To" and "References" header fields when replying so others can thread us. 4) Implement threading, sorting, and tagging, supported by the following commands: 'flatten', 'reverse', 'sort', 'thread', 'unthread', 'down', 'tset', 'up', 'expose', 'hide', 'tag', 'untag', 'invtags', 'tagbelow', 'hidetags', 'showtags'. See the manpage for details (when available - soon). 5) Implement a 'deldups' command to delete duplicate messages based on their "Message-Id" field, e.g., in replies to a mailing list that are also CCed to a subscriber. (This can also be accomplished with the threading and tagging commands.) 6) Implement 'ifdef' and 'ifndef' commands, and make the conditionals nestable (i.e., implement a conditional stack). The if/else/endif commands existed before, but they were primitive and undocumented. The 'if' command currently recognizes the "receiving", "sending", and "headersonly" mode keywords. 7) Teach the message selecting routine to understand regular expressions if "regex-search" is defined. Otherwise only case insensitive substring matches are done (as in the past). 8) Teach the message selection routine to understand boolean expressions. Improved "colon-modifier" support. See the manpage for details (when available - soon). 9) Extend paging to all commands (where relevant). 10) Add shell like piping and redirection of (standard) output (if "enable-piping" is defined). Extend completion to these contexts. 11) The manpage should follow soon!!!!
2006-11-28 21:45:32 +03:00
return 0;
}
#endif /* THREAD_SUPPORT */