NetBSD/usr.bin/mail/format.c

1072 lines
26 KiB
C
Raw Normal View History

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
/* $NetBSD: format.c,v 1.14 2009/04/10 13:08:24 christos Exp $ */
2006-11-01 01:36:37 +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.
*/
#include <sys/cdefs.h>
#ifndef __lint__
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
__RCSID("$NetBSD: format.c,v 1.14 2009/04/10 13:08:24 christos Exp $");
2006-11-01 01:36:37 +03:00
#endif /* not __lint__ */
#include <time.h>
#include <stdio.h>
#include <util.h>
#include "def.h"
#include "extern.h"
#include "format.h"
#include "glob.h"
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
#include "thread.h"
2006-11-01 01:36:37 +03:00
#undef DEBUG
#ifdef DEBUG
#define DPRINTF(a) printf a
#else
#define DPRINTF(a)
#endif
2006-11-01 01:36:37 +03:00
static void
check_bufsize(char **buf, size_t *bufsize, char **p, size_t cnt)
{
char *q;
if (*p + cnt < *buf + *bufsize)
return;
*bufsize *= 2;
q = erealloc(*buf, *bufsize);
2006-11-01 01:36:37 +03:00
*p = q + (*p - *buf);
*buf = q;
}
static const char *
sfmtoff(const char **fmtbeg, const char *fmtch, off_t off)
{
char *newfmt; /* pointer to new format string */
size_t len; /* space for "lld" including '\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
char *p;
2006-11-01 01:36:37 +03:00
len = fmtch - *fmtbeg + sizeof(PRId64);
newfmt = salloc(len);
(void)strlcpy(newfmt, *fmtbeg, len - sizeof(PRId64) + 1);
2006-11-01 01:36:37 +03:00
(void)strlcat(newfmt, PRId64, len);
*fmtbeg = fmtch + 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
(void)sasprintf(&p, newfmt, off);
return p;
2006-11-01 01:36:37 +03:00
}
static const char *
sfmtint(const char **fmtbeg, const char *fmtch, int num)
{
char *newfmt;
size_t len;
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
char *p;
2006-11-01 01:36:37 +03:00
len = fmtch - *fmtbeg + 2; /* space for 'd' and '\0' */
newfmt = salloc(len);
(void)strlcpy(newfmt, *fmtbeg, len);
newfmt[len-2] = 'd'; /* convert to printf format */
*fmtbeg = fmtch + 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
(void)sasprintf(&p, newfmt, num);
return p;
2006-11-01 01:36:37 +03:00
}
static const char *
sfmtstr(const char **fmtbeg, const char *fmtch, const char *str)
{
char *newfmt;
size_t len;
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
char *p;
2006-11-01 01:36:37 +03:00
len = fmtch - *fmtbeg + 2; /* space for 's' and '\0' */
newfmt = salloc(len);
(void)strlcpy(newfmt, *fmtbeg, len);
newfmt[len-2] = 's'; /* convert to printf format */
*fmtbeg = fmtch + 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
(void)sasprintf(&p, newfmt, str ? str : "");
return p;
}
#ifdef THREAD_SUPPORT
static char*
sfmtdepth(char *str, int depth)
{
char *p;
if (*str == '\0') {
(void)sasprintf(&p, "%d", depth);
return p;
2006-11-01 01:36:37 +03:00
}
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
p = __UNCONST("");
for (/*EMPTY*/; depth > 0; depth--)
(void)sasprintf(&p, "%s%s", p, str);
return p;
2006-11-01 01:36:37 +03:00
}
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
2006-11-01 01:36:37 +03:00
static const char *
sfmtfield(const char **fmtbeg, const char *fmtch, struct message *mp)
{
char *q;
q = strchr(fmtch + 1, '?');
if (q) {
size_t len;
char *p;
const char *str;
int skin_it;
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 THREAD_SUPPORT
int depth;
#endif
if (mp == NULL) {
*fmtbeg = q + 1;
return NULL;
}
#ifdef THREAD_SUPPORT
depth = mp->m_depth;
#endif
skin_it = 0;
switch (fmtch[1]) { /* check the '?' modifier */
#ifdef THREAD_SUPPORT
case '&': /* use the relative depth */
depth -= thread_depth();
/* FALLTHROUGH */
case '*': /* use the absolute depth */
len = q - fmtch - 1;
p = salloc(len);
(void)strlcpy(p, fmtch + 2, len);
p = sfmtdepth(p, depth);
break;
#endif
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
case '-':
skin_it = 1;
/* FALLTHROUGH */
default:
len = q - fmtch - skin_it;
p = salloc(len);
(void)strlcpy(p, fmtch + skin_it + 1, len);
p = hfield(p, mp);
if (skin_it)
p = skin(p);
break;
}
str = sfmtstr(fmtbeg, fmtch, p);
2006-11-01 01:36:37 +03:00
*fmtbeg = q + 1;
return str;
}
return 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
struct flags_s {
int f_and;
int f_or;
int f_new; /* some message in the thread is new */
int f_unread; /* some message in the thread is unread */
};
static void
get_and_or_flags(struct message *mp, struct flags_s *flags)
{
for (/*EMPTY*/; mp; mp = mp->m_flink) {
flags->f_and &= mp->m_flag;
flags->f_or |= mp->m_flag;
flags->f_new |= (mp->m_flag & (MREAD|MNEW)) == MNEW;
flags->f_unread |= (mp->m_flag & (MREAD|MNEW)) == 0;
get_and_or_flags(mp->m_clink, flags);
}
}
2006-11-01 01:36:37 +03:00
static const char *
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
sfmtflag(const char **fmtbeg, const char *fmtch, struct message *mp)
2006-11-01 01:36:37 +03:00
{
char disp[2];
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 flags_s flags;
int is_thread;
if (mp == NULL)
return 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
is_thread = mp->m_clink != NULL;
disp[0] = is_thread ? '+' : ' ';
2006-11-01 01:36:37 +03:00
disp[1] = '\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
flags.f_and = mp->m_flag;
flags.f_or = mp->m_flag;
flags.f_new = 0;
flags.f_unread = 0;
#ifdef THREAD_SUPPORT
if (thread_hidden())
get_and_or_flags(mp->m_clink, &flags);
#endif
if (flags.f_or & MTAGGED)
disp[0] = 't';
if (flags.f_and & MTAGGED)
disp[0] = 'T';
if (flags.f_or & MMODIFY)
disp[0] = 'e';
if (flags.f_and & MMODIFY)
disp[0] = 'E';
if (flags.f_or & MSAVED)
disp[0] = '&';
if (flags.f_and & MSAVED)
2006-11-01 01:36:37 +03:00
disp[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 (flags.f_or & MPRESERVE)
disp[0] = 'p';
if (flags.f_and & MPRESERVE)
2006-11-01 01:36:37 +03:00
disp[0] = '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
if (flags.f_unread)
disp[0] = 'u';
if ((flags.f_or & (MREAD|MNEW)) == 0)
2006-11-01 01:36:37 +03:00
disp[0] = 'U';
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 (flags.f_new)
disp[0] = 'n';
if ((flags.f_and & (MREAD|MNEW)) == MNEW)
disp[0] = 'N';
if (flags.f_or & MBOX)
disp[0] = 'm';
if (flags.f_and & MBOX)
2006-11-01 01:36:37 +03:00
disp[0] = 'M';
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
2006-11-01 01:36:37 +03:00
return sfmtstr(fmtbeg, fmtch, disp);
}
static const char *
login_name(const char *addr)
{
char *p;
p = strchr(addr, '@');
if (p) {
char *q;
size_t len;
len = p - addr + 1;
q = salloc(len);
(void)strlcpy(q, addr, len);
return q;
}
return addr;
}
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
/*
* A simple routine to get around a lint warning.
*/
static inline const char *
skip_fmt(const char **src, const char *p)
{
*src = p;
return NULL;
}
2006-11-01 01:36:37 +03:00
static const char *
subformat(const char **src, struct message *mp, const char *addr,
const char *user, const char *subj, int tm_isdst)
2006-11-01 01:36:37 +03:00
{
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 0
/* XXX - lint doesn't like this, hence skip_fmt(). */
#define MP(a) mp ? a : (*src = (p + 1), NULL)
#else
#define MP(a) mp ? a : skip_fmt(src, p + 1);
#endif
2006-11-01 01:36:37 +03:00
const char *p;
p = *src;
if (p[1] == '%') {
*src += 2;
return "%%";
}
for (p = *src; *p && !isalpha((unsigned char)*p) && *p != '?'; p++)
continue;
switch (*p) {
/*
* Our format extensions to strftime(3)
*/
2006-11-01 01:36:37 +03:00
case '?':
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 sfmtfield(src, p, mp);
2006-11-01 01:36:37 +03:00
case '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
return MP(sfmtint(src, p, (int)(mp->m_lines - mp->m_blines)));
2006-11-01 01:36:37 +03:00
case 'K':
return MP(sfmtint(src, p, (int)mp->m_blines));
case 'L':
return MP(sfmtint(src, p, (int)mp->m_lines));
case 'N':
return sfmtstr(src, p, user);
case 'O':
return MP(sfmtoff(src, p, mp->m_size));
case 'P':
return MP(sfmtstr(src, p, mp == dot ? ">" : " "));
case 'Q':
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(sfmtflag(src, p, mp));
2006-11-01 01:36:37 +03:00
case 'f':
return sfmtstr(src, p, addr);
case '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
return sfmtint(src, p, get_msgnum(mp)); /* '0' if mp == NULL */
2006-11-01 01:36:37 +03:00
case 'n':
return sfmtstr(src, p, login_name(addr));
case 'q':
return sfmtstr(src, p, subj);
case 't':
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 sfmtint(src, p, get_msgCount());
/*
* strftime(3) special cases:
*
* When 'tm_isdst' was not determined (i.e., < 0), a C99
* compliant strftime(3) will output an empty string for the
* "%Z" and "%z" formats. This messes up alignment so we
* handle these ourselves.
*/
case 'Z':
if (tm_isdst < 0) {
*src = p + 1;
return "???"; /* XXX - not ideal */
}
return NULL;
2006-11-01 01:36:37 +03:00
case 'z':
if (tm_isdst < 0) {
*src = p + 1;
return "-0000"; /* consistent with RFC 2822 */
}
return NULL;
/* everything else is handled by strftime(3) */
2006-11-01 01:36:37 +03:00
default:
return NULL;
}
#undef MP
}
static const char *
snarf_comment(char **buf, char *bufend, const char *string)
{
const char *p;
char *q;
char *qend;
int clevel;
q = buf ? *buf : NULL;
qend = buf ? bufend : NULL;
clevel = 1;
for (p = string + 1; *p != '\0'; p++) {
DPRINTF(("snarf_comment: %s\n", p));
2006-11-01 01:36:37 +03:00
if (*p == '(') {
clevel++;
continue;
}
if (*p == ')') {
if (--clevel == 0)
break;
continue;
}
if (*p == '\\' && p[1] != 0)
p++;
if (q < qend)
*q++ = *p;
}
if (buf) {
*q = '\0';
DPRINTF(("snarf_comment: terminating: %s\n", *buf));
2006-11-01 01:36:37 +03:00
*buf = q;
}
if (*p == '\0')
p--;
return p;
}
static const char *
snarf_quote(char **buf, char *bufend, const char *string)
{
const char *p;
char *q;
char *qend;
q = buf ? *buf : NULL;
qend = buf ? bufend : NULL;
for (p = string + 1; *p != '\0' && *p != '"'; p++) {
DPRINTF(("snarf_quote: %s\n", p));
2006-11-01 01:36:37 +03:00
if (*p == '\\' && p[1] != '\0')
p++;
if (q < qend)
*q++ = *p;
}
if (buf) {
*q = '\0';
DPRINTF(("snarf_quote: terminating: %s\n", *buf));
2006-11-01 01:36:37 +03:00
*buf = q;
}
if (*p == '\0')
p--;
return p;
}
/*
* Grab the comments, separating each by a space.
*/
static char *
get_comments(char *name)
{
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
char nbuf[LINESIZE];
2006-11-01 01:36:37 +03:00
const char *p;
char *qend;
char *q;
char *lastq;
if (name == 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
return NULL;
2006-11-01 01:36:37 +03:00
p = name;
q = nbuf;
lastq = nbuf;
qend = nbuf + sizeof(nbuf) - 1;
for (p = skip_WSP(name); *p != '\0'; p++) {
DPRINTF(("get_comments: %s\n", p));
2006-11-01 01:36:37 +03:00
switch (*p) {
case '"': /* quoted-string ... skip it! */
p = snarf_quote(NULL, NULL, p);
break;
case '(':
p = snarf_comment(&q, qend, p);
lastq = q;
if (q < qend) /* separate comments by space */
*q++ = ' ';
2006-11-01 01:36:37 +03:00
break;
default:
break;
}
}
*lastq = '\0';
return savestr(nbuf);
}
/*
* Convert a possible obs_zone (see RFC 2822, sec 4.3) to a valid
* gmtoff string.
*/
static const char *
convert_obs_zone(const char *obs_zone)
{
static const struct obs_zone_tbl_s {
const char *zone;
const char *gmtoff;
} obs_zone_tbl[] = {
{"UT", "+0000"},
{"GMT", "+0000"},
{"EST", "-0500"},
{"EDT", "-0400"},
{"CST", "-0600"},
{"CDT", "-0500"},
{"MST", "-0700"},
{"MDT", "-0600"},
{"PST", "-0800"},
{"PDT", "-0700"},
{NULL, NULL},
};
const struct obs_zone_tbl_s *zp;
if (obs_zone[0] == '+' || obs_zone[0] == '-')
return obs_zone;
if (obs_zone[1] == 0) { /* possible military zones */
/* be explicit here - avoid C extensions and ctype(3) */
switch((unsigned char)obs_zone[0]) {
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
return "-0000"; /* See RFC 2822, sec 4.3 */
default:
return obs_zone;
}
}
for (zp = obs_zone_tbl; zp->zone; zp++) {
if (strcmp(obs_zone, zp->zone) == 0)
return zp->gmtoff;
}
return obs_zone;
}
/*
* Parse the 'Date:" field into a tm structure and return the gmtoff
* string or NULL on error.
*/
static const char *
date_to_tm(char *date, struct tm *tm)
{
/****************************************************************
* The header 'date-time' syntax - From RFC 2822 sec 3.3 and 4.3:
*
* date-time = [ day-of-week "," ] date FWS time [CFWS]
* day-of-week = ([FWS] day-name) / obs-day-of-week
* day-name = "Mon" / "Tue" / "Wed" / "Thu" /
* "Fri" / "Sat" / "Sun"
* date = day month year
* year = 4*DIGIT / obs-year
* month = (FWS month-name FWS) / obs-month
* month-name = "Jan" / "Feb" / "Mar" / "Apr" /
* "May" / "Jun" / "Jul" / "Aug" /
* "Sep" / "Oct" / "Nov" / "Dec"
* day = ([FWS] 1*2DIGIT) / obs-day
* time = time-of-day FWS zone
* time-of-day = hour ":" minute [ ":" second ]
* hour = 2DIGIT / obs-hour
* minute = 2DIGIT / obs-minute
* second = 2DIGIT / obs-second
* zone = (( "+" / "-" ) 4DIGIT) / obs-zone
*
* obs-day-of-week = [CFWS] day-name [CFWS]
* obs-year = [CFWS] 2*DIGIT [CFWS]
* obs-month = CFWS month-name CFWS
* obs-day = [CFWS] 1*2DIGIT [CFWS]
* obs-hour = [CFWS] 2DIGIT [CFWS]
* obs-minute = [CFWS] 2DIGIT [CFWS]
* obs-second = [CFWS] 2DIGIT [CFWS]
****************************************************************/
/*
* For example, a typical date might look like:
*
* Date: Mon, 1 Oct 2007 05:38:10 +0000 (UTC)
*/
char *tail;
char *p;
struct tm tmp_tm;
/*
* NOTE: Rather than depend on strptime(3) modifying only
* those fields specified in its format string, we use tmp_tm
* and copy the appropriate result to tm. This is not
* required with the NetBSD strptime(3) implementation.
*/
/* Check for an optional 'day-of-week' */
if ((tail = strptime(date, " %a,", &tmp_tm)) == NULL) {
tail = date;
tm->tm_wday = tmp_tm.tm_wday;
}
/* Get the required 'day' and 'month' */
if ((tail = strptime(tail, " %d %b", &tmp_tm)) == NULL)
return NULL;
tm->tm_mday = tmp_tm.tm_mday;
tm->tm_mon = tmp_tm.tm_mon;
/* Check for 'obs-year' (2 digits) before 'year' (4 digits) */
/* XXX - Portable? This depends on strptime not scanning off
* trailing whitespace unless specified in the format string.
*/
if ((p = strptime(tail, " %y", &tmp_tm)) != NULL && is_WSP(*p))
tail = p;
else if ((tail = strptime(tail, " %Y", &tmp_tm)) == NULL)
return NULL;
tm->tm_year = tmp_tm.tm_year;
/* Get the required 'hour' and 'minute' */
if ((tail = strptime(tail, " %H:%M", &tmp_tm)) == NULL)
return NULL;
tm->tm_hour = tmp_tm.tm_hour;
tm->tm_min = tmp_tm.tm_min;
/* Check for an optional 'seconds' field */
if ((p = strptime(tail, ":%S", &tmp_tm)) != NULL) {
tail = p;
tm->tm_sec = tmp_tm.tm_sec;
}
tail = skip_WSP(tail);
/*
* The timezone name is frequently in a comment following the
* zone offset.
*
* XXX - this will get overwritten later by timegm(3).
*/
if ((p = strchr(tail, '(')) != NULL)
tm->tm_zone = get_comments(p);
else
tm->tm_zone = NULL;
/* what remains should be the gmtoff string */
tail = skin(tail);
return convert_obs_zone(tail);
}
/*
* Parse the headline string into a tm structure. Returns a pointer
* to first non-whitespace after the date or NULL on error.
*
* XXX - This needs to be consistent with isdate().
*/
static char *
hl_date_to_tm(const char *buf, struct tm *tm)
{
/****************************************************************
* The BSD and System V headline date formats differ
* and each have an optional timezone field between
* the time and date (see head.c). Unfortunately,
* strptime(3) doesn't know about timezone fields, so
* we have to handle it ourselves.
*
* char ctype[] = "Aaa Aaa O0 00:00:00 0000";
* char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000";
* char SysV_ctype[] = "Aaa Aaa O0 00:00 0000";
* char SysV_tmztype[] = "Aaa Aaa O0 00:00 AAA 0000";
****************************************************************/
char *tail;
char *p;
char zone[4];
struct tm tmp_tm; /* see comment in date_to_tm() */
int len;
zone[0] = '\0';
if ((tail = strptime(buf, " %a %b %d %H:%M", &tmp_tm)) == NULL)
return NULL;
tm->tm_wday = tmp_tm.tm_wday;
tm->tm_mday = tmp_tm.tm_mday;
tm->tm_mon = tmp_tm.tm_mon;
tm->tm_hour = tmp_tm.tm_hour;
tm->tm_min = tmp_tm.tm_min;
/* Check for an optional 'seconds' field */
if ((p = strptime(tail, ":%S", &tmp_tm)) != NULL) {
tail = p;
tm->tm_sec = tmp_tm.tm_sec;
}
/* Grab an optional timezone name */
/*
* XXX - Is the zone name always 3 characters as in isdate()?
*/
if (sscanf(tail, " %3[A-Z] %n", zone, &len) == 1) {
if (zone[0])
tm->tm_zone = savestr(zone);
tail += len;
}
/* Grab the required year field */
tail = strptime(tail, " %Y ", &tmp_tm);
tm->tm_year = tmp_tm.tm_year; /* save this even if it failed */
return tail;
}
2006-11-01 01:36:37 +03:00
/*
* Get the date and time info from the "Date:" line, parse it into a
* tm structure as much as possible.
*
* Note: We return the gmtoff as a string as "-0000" has special
* meaning. See RFC 2822, sec 3.3.
*/
PUBLIC void
2006-11-01 01:36:37 +03:00
dateof(struct tm *tm, struct message *mp, int use_hl_date)
{
static int tzinit = 0;
char *date = NULL;
const char *gmtoff;
2006-11-01 01:36:37 +03:00
(void)memset(tm, 0, sizeof(*tm));
/* Make sure the time zone info is initialized. */
if (!tzinit) {
tzinit = 1;
tzset();
}
2006-11-01 01:36:37 +03:00
if (mp == NULL) { /* use local time */
time_t now;
(void)time(&now);
(void)localtime_r(&now, tm);
return;
2006-11-01 01:36:37 +03:00
}
2006-11-01 01:36:37 +03:00
/*
* See RFC 2822 sec 3.3 for date-time format used in
* the "Date:" field.
*
* NOTE: The range for the time is 00:00 to 23:60 (to allow
* for a leep second), but I have seen this violated making
* strptime() fail, e.g.,
2006-11-01 01:36:37 +03:00
*
* Date: Tue, 24 Oct 2006 24:07:58 +0400
2006-11-01 01:36:37 +03:00
*
* In this case we (silently) fall back to the headline time
* which was written locally when the message was received.
* Of course, this is not the same time as in the Date field.
2006-11-01 01:36:37 +03:00
*/
if (use_hl_date == 0 &&
(date = hfield("date", mp)) != NULL &&
(gmtoff = date_to_tm(date, tm)) != 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
int hour;
int min;
char sign[2];
struct tm save_tm;
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
/*
* Scan the gmtoff and use it to convert the time to a
* local time.
*
* Note: "-0000" means no valid zone info. See
* RFC 2822, sec 3.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
* XXX - This is painful! Is there a better way?
*/
tm->tm_isdst = -1; /* let timegm(3) determine tm_isdst */
save_tm = *tm; /* use this if we fail */
if (strcmp(gmtoff, "-0000") != 0 &&
sscanf(gmtoff, " %1[+-]%2d%2d ", sign, &hour, &min) == 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
time_t otime;
if (sign[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
tm->tm_hour += hour;
tm->tm_min += min;
}
else {
tm->tm_hour -= hour;
tm->tm_min -= min;
}
if ((otime = timegm(tm)) == (time_t)-1 ||
localtime_r(&otime, tm) == NULL) {
if (debug)
warnx("cannot convert date: \"%s\"", date);
*tm = save_tm;
}
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
}
else { /* Unable to do the conversion to local time. */
*tm = save_tm;
/* tm->tm_isdst = -1; */ /* Set above */
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
tm->tm_gmtoff = 0;
tm->tm_zone = NULL;
}
2006-11-01 01:36:37 +03:00
}
else {
struct headline hl;
char headline[LINESIZE];
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
char pbuf[LINESIZE];
if (debug && use_hl_date == 0)
warnx("invalid date: \"%s\"", date ? date : "<null>");
/*
* The headline is written locally so failures here
* should be seen (i.e., not conditional on 'debug').
*/
tm->tm_isdst = -1; /* let mktime(3) determine tm_isdst */
2006-11-01 01:36:37 +03:00
headline[0] = '\0';
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
(void)readline(setinput(mp), headline, (int)sizeof(headline), 0);
2006-11-01 01:36:37 +03:00
parse(headline, &hl, pbuf);
if (hl.l_date == NULL)
warnx("invalid headline: `%s'", headline);
else if (hl_date_to_tm(hl.l_date, tm) == NULL ||
mktime(tm) == -1)
warnx("invalid headline date: `%s'", hl.l_date);
2006-11-01 01:36:37 +03:00
}
}
/*
* Get the sender's address for display. Let nameof() do this.
*/
static const char *
addrof(struct message *mp)
{
if (mp == NULL)
return NULL;
return nameof(mp, 0);
}
/************************************************************************
* The 'address' syntax - from RFC 2822:
2006-11-01 01:36:37 +03:00
*
* specials = "(" / ")" / ; Special characters used in
* "<" / ">" / ; other parts of the syntax
* "[" / "]" /
* ":" / ";" /
* "@" / "\" /
* "," / "." /
* DQUOTE
* qtext = NO-WS-CTL / ; Non white space controls
* %d33 / ; The rest of the US-ASCII
* %d35-91 / ; characters not including "\"
* %d93-126 ; or the quote character
* qcontent = qtext / quoted-pair
* quoted-string = [CFWS]
* DQUOTE *([FWS] qcontent) [FWS] DQUOTE
* [CFWS]
* atext = ALPHA / DIGIT / ; Any character except controls,
* "!" / "#" / ; SP, and specials.
* "$" / "%" / ; Used for atoms
* "&" / "'" /
* "*" / "+" /
* "-" / "/" /
* "=" / "?" /
* "^" / "_" /
* "`" / "{" /
* "|" / "}" /
* "~"
* atom = [CFWS] 1*atext [CFWS]
* word = atom / quoted-string
* phrase = 1*word / obs-phrase
* display-name = phrase
* dtext = NO-WS-CTL / ; Non white space controls
* %d33-90 / ; The rest of the US-ASCII
* %d94-126 ; characters not including "[",
* ; "]", or "\"
* dcontent = dtext / quoted-pair
* domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
* domain = dot-atom / domain-literal / obs-domain
* local-part = dot-atom / quoted-string / obs-local-part
* addr-spec = local-part "@" domain
* angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
* name-addr = [display-name] angle-addr
* mailbox = name-addr / addr-spec
* mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
* group = display-name ":" [mailbox-list / CFWS] ";"
* [CFWS]
* address = mailbox / group
************************************************************************/
static char *
get_display_name(char *name)
{
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
char nbuf[LINESIZE];
2006-11-01 01:36:37 +03:00
const char *p;
char *q;
char *qend;
char *lastq;
int quoted;
if (name == 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
return NULL;
2006-11-01 01:36:37 +03:00
q = nbuf;
lastq = nbuf;
qend = nbuf + sizeof(nbuf) - 1; /* reserve space for '\0' */
quoted = 0;
for (p = skip_WSP(name); *p != '\0'; p++) {
DPRINTF(("get_display_name: %s\n", p));
2006-11-01 01:36:37 +03:00
switch (*p) {
case '"': /* quoted-string */
q = nbuf;
p = snarf_quote(&q, qend, p);
if (!quoted)
lastq = q;
quoted = 1;
break;
case ':': /* group */
case '<': /* angle-address */
if (lastq == nbuf)
return NULL;
*lastq = '\0'; /* NULL termination */
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 savestr(nbuf);
2006-11-01 01:36:37 +03:00
case '(': /* comment - skip it! */
p = snarf_comment(NULL, NULL, p);
break;
default:
if (!quoted && q < qend) {
*q++ = *p;
if (!is_WSP(*p)
2006-11-01 01:36:37 +03:00
/* && !is_specials((unsigned char)*p) */ )
lastq = q;
}
break;
}
}
return NULL; /* no group or angle-address */
}
/*
* See RFC 2822 sec 3.4 and 3.6.2.
*/
static const char *
userof(struct message *mp)
{
char *sender;
char *dispname;
if (mp == NULL)
return NULL;
if ((sender = hfield("from", mp)) != NULL ||
(sender = hfield("sender", mp)) != NULL)
/*
* Try to get the display-name. If one doesn't exist,
* then the best we can hope for is that the user's
* name is in the comments.
*/
if ((dispname = get_display_name(sender)) != NULL ||
(dispname = get_comments(sender)) != NULL)
return dispname;
return NULL;
}
/*
* Grab the subject line.
*/
static const char *
subjof(struct message *mp)
{
const char *subj;
if (mp == NULL)
return NULL;
if ((subj = hfield("subject", mp)) == NULL)
subj = hfield("subj", mp);
return subj;
}
2007-07-07 00:14:33 +04:00
/*
* Protect a string against strftime() conversion.
*/
static const char*
protect(const char *str)
{
char *p, *q;
size_t size;
2007-07-07 21:53:13 +04:00
if (str == NULL || (size = strlen(str)) == 0)
2007-07-07 00:14:33 +04:00
return str;
2007-07-07 22:04:17 +04:00
p = salloc(2 * size + 1);
2007-07-07 00:14:33 +04:00
for (q = p; *str; str++) {
*q = *str;
if (*q++ == '%')
*q++ = '%';
}
*q = '\0';
return p;
}
2006-11-01 01:36:37 +03:00
static char *
preformat(struct tm *tm, const char *oldfmt, struct message *mp, int use_hl_date)
{
const char *subj;
const char *addr;
const char *user;
const char *p;
char *q;
char *newfmt;
size_t fmtsize;
if (mp != NULL && (mp->m_flag & MDELETED) != 0)
mp = NULL; /* deleted mail shouldn't show up! */
2007-07-07 00:14:33 +04:00
subj = protect(subjof(mp));
addr = protect(addrof(mp));
user = protect(userof(mp));
dateof(tm, mp, use_hl_date);
2006-11-01 01:36:37 +03:00
fmtsize = LINESIZE;
newfmt = ecalloc(1, fmtsize); /* so we can realloc() in check_bufsize() */
2006-11-01 01:36:37 +03:00
q = newfmt;
p = oldfmt;
while (*p) {
if (*p == '%') {
const char *fp;
fp = subformat(&p, mp, addr, user, subj, tm->tm_isdst);
2006-11-01 01:36:37 +03:00
if (fp) {
size_t len;
len = strlen(fp);
check_bufsize(&newfmt, &fmtsize, &q, len);
(void)strcpy(q, fp);
q += len;
continue;
}
}
check_bufsize(&newfmt, &fmtsize, &q, 1);
*q++ = *p++;
}
*q = '\0';
return newfmt;
}
/*
* If a format string begins with the USE_HL_DATE string, smsgprintf
* will use the headerline date rather than trying to extract the date
* from the Date field.
*
* Note: If a 'valid' date cannot be extracted from the Date field,
* then the headline date is used.
*/
#define USE_HL_DATE "%??"
PUBLIC char *
smsgprintf(const char *fmtstr, struct message *mp)
{
struct tm tm;
int use_hl_date;
char *newfmt;
char *buf;
size_t bufsize;
if (strncmp(fmtstr, USE_HL_DATE, sizeof(USE_HL_DATE) - 1) != 0)
use_hl_date = 0;
else {
use_hl_date = 1;
fmtstr += sizeof(USE_HL_DATE) - 1;
}
bufsize = LINESIZE;
buf = salloc(bufsize);
newfmt = preformat(&tm, fmtstr, mp, use_hl_date);
(void)strftime(buf, bufsize, newfmt, &tm);
free(newfmt); /* preformat() uses malloc()/realloc() */
return buf;
}
PUBLIC void
fmsgprintf(FILE *fo, const char *fmtstr, struct message *mp)
{
char *buf;
buf = smsgprintf(fmtstr, mp);
(void)fprintf(fo, "%s\n", buf); /* XXX - add the newline here? */
}