NetBSD/usr.bin/mail/collect.c

791 lines
18 KiB
C
Raw Normal View History

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
/* $NetBSD: collect.c,v 1.37 2006/11/28 18:45:32 christos Exp $ */
1993-03-21 12:45:37 +03:00
/*
1994-06-29 09:09:04 +04:00
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
1993-03-21 12:45:37 +03:00
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
1993-03-21 12:45:37 +03:00
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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>
1993-03-21 12:45:37 +03:00
#ifndef lint
#if 0
static char sccsid[] = "@(#)collect.c 8.2 (Berkeley) 4/19/94";
#else
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
__RCSID("$NetBSD: collect.c,v 1.37 2006/11/28 18:45:32 christos Exp $");
#endif
1993-03-21 12:45:37 +03:00
#endif /* not lint */
/*
* Mail -- a mail program
*
* Collect input from standard input, handling
* ~ escapes.
*/
#include <assert.h>
#include <util.h>
1993-03-21 12:45:37 +03:00
#include "rcv.h"
1994-06-29 09:09:04 +04:00
#include "extern.h"
#include "format.h"
#ifdef MIME_SUPPORT
#include "mime.h"
#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
#include "thread.h"
1993-03-21 12:45:37 +03:00
1993-03-21 12:45:37 +03:00
/*
* Read a message from standard input and return a read file to it
1993-03-21 12:45:37 +03:00
* or NULL on error.
*/
/*
* The following hokiness with global variables is so that on
* receipt of an interrupt signal, the partial message can be salted
* away on dead.letter.
*/
static sig_t saveint; /* Previous SIGINT value */
static sig_t savehup; /* Previous SIGHUP value */
static sig_t savetstp; /* Previous SIGTSTP value */
static sig_t savettou; /* Previous SIGTTOU value */
static sig_t savettin; /* Previous SIGTTIN value */
static FILE *collf; /* File for saving away */
static int hadintr; /* Have seen one SIGINT so far */
static jmp_buf colljmp; /* To get back to work */
static int colljmp_p; /* whether to long jump */
static jmp_buf collabort; /* To end collection with error */
Jumbo mail patch from our anonymous user: 1) Use editline [optional]: Most of this code was borrowed from src/usr.bin/ftp. It does the appropriate editing, history, and completion for all mail commands (from cmdtab[]) and also does editing on header strings ('~h' inside the mail editor). 2) '-B' flag: This will suppress the "To:" line passed to sendmail. In most configurations it will lead to sendmail adding "To: undisclosed recipients;". Currently, AFAIK mail requires at least one exposed recipient address. 3) Comments in rcfile: Currently, comments in .mailrc are only supported if the first (non-white) character on a line is '#' followed by white space, i.e., '#' is a 'nop' command. This (trivial) patch allows the more normal/expected use of '#' as a comment character. It does not respect quoting, so that might be an objection which I should fix. 4) Sendmail option editing: This adds the sendmail option string to the strings editable by the '~h' command within the mail editor. Currently, you can only set this string from the command-line, which is particularly annoying when replying to mail. 5) Reply from: When replying to a message, grab the "To:" address from the message and, if there is only one such address and it does not match a list of allowed addresses (set in the "ReplyFrom" variable), pass it to sendmail as the "From:" address for the reply (with the '-f' option). I often make aliases for myself so that my primary address is not given out; if the alias gets out, I know who to blame. Unfortunately, a reply to such a message would normally use the primary address without this patch. A warning is displayed when this is going to happen so that it can be modified with '~h'. 6) CC and BCC lists: Allow '-c' and '-b' to accept white-space or ',' delimited lists. Currently, a white-space delimited list of addresses work, but a list of aliases will not get expanded. For example, currently: mail -c "foo bar" christos will fail to send mail to 'foo' and 'bar' if these are mail aliases (in ~/.mailrc); sendmail aliases (in /etc/aliases) do work. 7) pipe command: This pipes the current message into a shell command. I use this for quick decoding of uuencoded mail, but I can imagine it might be useful for decrypting encrypted mail, too. 8) show command: This command takes a list of variables and shows their values. It is probably stupid as the 'set' command without any argument displays all variable values. Of course, if there are a lot of variables you have to sift through the list for the one(s) you want.
2006-09-18 23:46:21 +04: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
/*
* Write a file, ex-like if f set.
*/
static int
exwrite(const char name[], FILE *fp, int f)
{
FILE *of;
int c;
long cc;
int lc;
struct stat junk;
if (f) {
(void)printf("\"%s\" ", name);
(void)fflush(stdout);
}
if (stat(name, &junk) >= 0 && S_ISREG(junk.st_mode)) {
if (!f)
(void)fprintf(stderr, "%s: ", name);
(void)fprintf(stderr, "File exists\n");
return -1;
}
if ((of = Fopen(name, "w")) == NULL) {
warn("%s", name);
return -1;
}
lc = 0;
cc = 0;
while ((c = getc(fp)) != EOF) {
cc++;
if (c == '\n')
lc++;
(void)putc(c, of);
if (ferror(of)) {
warn("%s", name);
(void)Fclose(of);
return -1;
}
}
(void)Fclose(of);
(void)printf("%d/%ld\n", lc, cc);
(void)fflush(stdout);
return 0;
}
/*
* Edit the message being collected on fp.
* On return, make the edit file the new temp file.
*/
static void
mesedit(FILE *fp, int c)
{
sig_t sigint = signal(SIGINT, SIG_IGN);
FILE *nf = run_editor(fp, (off_t)-1, c, 0);
if (nf != NULL) {
(void)fseek(nf, 0L, 2);
collf = nf;
(void)Fclose(fp);
}
(void)signal(SIGINT, sigint);
}
/*
* Pipe the message through the command.
* Old message is on stdin of command;
* New message collected from stdout.
* Sh -c must return 0 to accept the new message.
*/
static void
mespipe(FILE *fp, char cmd[])
{
FILE *nf;
sig_t sigint = signal(SIGINT, SIG_IGN);
const char *shellcmd;
int fd;
char tempname[PATHSIZE];
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.ReXXXXXXXXXX", tmpdir);
if ((fd = mkstemp(tempname)) == -1 ||
(nf = Fdopen(fd, "w+")) == NULL) {
if (fd != -1)
(void)close(fd);
warn("%s", tempname);
goto out;
}
(void)unlink(tempname);
/*
* stdin = current message.
* stdout = new message.
*/
if ((shellcmd = value(ENAME_SHELL)) == NULL)
shellcmd = _PATH_CSHELL;
if (run_command(shellcmd,
0, fileno(fp), fileno(nf), "-c", cmd, NULL) < 0) {
(void)Fclose(nf);
goto out;
}
if (fsize(nf) == 0) {
(void)fprintf(stderr, "No bytes from \"%s\" !?\n", cmd);
(void)Fclose(nf);
goto out;
}
/*
* Take new files.
*/
(void)fseek(nf, 0L, 2);
collf = nf;
(void)Fclose(fp);
out:
(void)signal(SIGINT, sigint);
}
/*
* Interpolate the named messages into the current
* message, preceding each line with a tab.
* Return a count of the number of characters now in
* the message, or -1 if an error is encountered writing
* the message temporary. The flag argument is 'm' if we
* should shift over and 'f' if not.
*/
static int
forward(char ms[], FILE *fp, char *fn, int f)
{
int *msgvec;
struct ignoretab *ig;
const char *tabst;
#ifdef MIME_SUPPORT
struct mime_info *mip;
int retval;
#endif
msgvec = salloc((get_msgCount() + 1) * sizeof *msgvec);
if (msgvec == NULL)
return 0;
if (getmsglist(ms, msgvec, 0) < 0)
return 0;
if (*msgvec == 0) {
*msgvec = first(0, MMNORM);
if (*msgvec == 0) {
(void)printf("No appropriate messages\n");
return 0;
}
msgvec[1] = 0;
}
if (f == 'f' || f == 'F')
tabst = NULL;
else if ((tabst = value(ENAME_INDENTPREFIX)) == NULL)
tabst = "\t";
ig = isupper(f) ? NULL : ignore;
(void)printf("Interpolating:");
for (; *msgvec != 0; msgvec++) {
struct message *mp;
char *fmtstr;
mp = get_message(*msgvec);
touch(mp);
(void)printf(" %d", *msgvec);
(void)fflush(stdout); /* flush stdout and the above */
if (tabst && (fmtstr = value(ENAME_INDENT_PREAMBLE)) != NULL)
fmsgprintf(collf, fmtstr, mp);
#ifdef MIME_SUPPORT
mip = NULL;
if (value(ENAME_MIME_DECODE_MSG)) {
if ((tabst == NULL && value(ENAME_MIME_DECODE_INSERT)) ||
(tabst != NULL && value(ENAME_MIME_DECODE_QUOTE)))
mip = mime_decode_open(mp);
}
retval = mime_sendmessage(mp, fp, ig, tabst, mip);
mime_decode_close(mip);
if (retval < 0)
#else
if (sendmessage(mp, fp, ig, tabst, NULL) < 0)
#endif
{
warn("%s", fn);
return -1;
}
if (tabst && (fmtstr = value(ENAME_INDENT_POSTSCRIPT)) != NULL)
fmsgprintf(collf, fmtstr, mp);
}
(void)printf("\n");
return 0;
}
/*
* Print (continue) when continued after ^Z.
*/
/*ARGSUSED*/
static void
collstop(int s)
{
sig_t old_action = signal(s, SIG_DFL);
sigset_t nset;
(void)sigemptyset(&nset);
(void)sigaddset(&nset, s);
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
(void)kill(0, s);
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
(void)signal(s, old_action);
if (colljmp_p) {
colljmp_p = 0;
hadintr = 0;
longjmp(colljmp, 1);
}
}
/*
* Append the contents of the file to the end of the deadletter file.
*/
PUBLIC void
savedeadletter(FILE *fp)
{
FILE *dbuf;
mode_t m;
int c;
const char *cp;
if (fsize(fp) == 0)
return;
cp = getdeadletter();
m = umask(077);
dbuf = Fopen(cp, "a");
(void)umask(m);
if (dbuf == NULL)
return;
while ((c = getc(fp)) != EOF)
(void)putc(c, dbuf);
(void)Fclose(dbuf);
rewind(fp);
}
/*
* On interrupt, come here to save the partial message in ~/dead.letter.
* Then jump out of the collection loop.
*/
/*ARGSUSED*/
static void
collint(int s __unused)
{
/*
* the control flow is subtle, because we can be called from ~q.
*/
if (!hadintr) {
if (value(ENAME_IGNORE) != NULL) {
(void)puts("@");
(void)fflush(stdout);
clearerr(stdin);
return;
}
hadintr = 1;
longjmp(colljmp, 1);
}
rewind(collf);
if (value(ENAME_NOSAVE) == NULL)
savedeadletter(collf);
longjmp(collabort, 1);
}
/*ARGSUSED*/
static void
collhup(int s __unused)
{
rewind(collf);
savedeadletter(collf);
/*
* Let's pretend nobody else wants to clean up,
* a true statement at this time.
*/
exit(1);
}
PUBLIC FILE *
2002-03-02 17:59:35 +03:00
collect(struct header *hp, int printheaders)
1993-03-21 12:45:37 +03:00
{
FILE *fbuf;
int lc, cc;
int c, fd, t;
2005-07-19 05:38:38 +04:00
char linebuf[LINESIZE];
const char *cp;
char tempname[PATHSIZE];
char mailtempname[PATHSIZE];
int lastlong, rc; /* So we don't make 2 or more lines
out of a long input line. */
int eofcount;
int longline;
sigset_t nset;
/* The following are declared volatile to avoid longjmp clobbering. */
char volatile getsub;
int volatile escape;
1993-03-21 12:45:37 +03:00
2005-07-20 03:07:10 +04:00
(void)memset(mailtempname, 0, sizeof(mailtempname));
1993-03-21 12:45:37 +03:00
collf = NULL;
/*
* Start catching signals from here, but we're still die on interrupts
* until we're in the main loop.
*/
(void)sigemptyset(&nset);
(void)sigaddset(&nset, SIGINT);
(void)sigaddset(&nset, SIGHUP);
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
1993-03-21 12:45:37 +03:00
if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
2005-07-20 03:07:10 +04:00
(void)signal(SIGINT, collint);
1993-03-21 12:45:37 +03:00
if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
2005-07-20 03:07:10 +04:00
(void)signal(SIGHUP, collhup);
1993-03-21 12:45:37 +03:00
savetstp = signal(SIGTSTP, collstop);
savettou = signal(SIGTTOU, collstop);
savettin = signal(SIGTTIN, collstop);
if (setjmp(collabort) || setjmp(colljmp)) {
(void)rm(mailtempname);
1993-03-21 12:45:37 +03:00
goto err;
}
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
1993-03-21 12:45:37 +03:00
noreset++;
(void)snprintf(mailtempname, sizeof(mailtempname),
"%s/mail.RsXXXXXXXXXX", tmpdir);
if ((fd = mkstemp(mailtempname)) == -1 ||
(collf = Fdopen(fd, "w+")) == NULL) {
if (fd != -1)
2005-07-20 03:07:10 +04:00
(void)close(fd);
warn("%s", mailtempname);
1993-03-21 12:45:37 +03:00
goto err;
}
(void)rm(mailtempname);
1993-03-21 12:45:37 +03:00
/*
* If we are going to prompt for a subject,
* refrain from printing a newline after
* the headers (since some people mind).
*/
Jumbo mail patch from our anonymous user: 1) Use editline [optional]: Most of this code was borrowed from src/usr.bin/ftp. It does the appropriate editing, history, and completion for all mail commands (from cmdtab[]) and also does editing on header strings ('~h' inside the mail editor). 2) '-B' flag: This will suppress the "To:" line passed to sendmail. In most configurations it will lead to sendmail adding "To: undisclosed recipients;". Currently, AFAIK mail requires at least one exposed recipient address. 3) Comments in rcfile: Currently, comments in .mailrc are only supported if the first (non-white) character on a line is '#' followed by white space, i.e., '#' is a 'nop' command. This (trivial) patch allows the more normal/expected use of '#' as a comment character. It does not respect quoting, so that might be an objection which I should fix. 4) Sendmail option editing: This adds the sendmail option string to the strings editable by the '~h' command within the mail editor. Currently, you can only set this string from the command-line, which is particularly annoying when replying to mail. 5) Reply from: When replying to a message, grab the "To:" address from the message and, if there is only one such address and it does not match a list of allowed addresses (set in the "ReplyFrom" variable), pass it to sendmail as the "From:" address for the reply (with the '-f' option). I often make aliases for myself so that my primary address is not given out; if the alias gets out, I know who to blame. Unfortunately, a reply to such a message would normally use the primary address without this patch. A warning is displayed when this is going to happen so that it can be modified with '~h'. 6) CC and BCC lists: Allow '-c' and '-b' to accept white-space or ',' delimited lists. Currently, a white-space delimited list of addresses work, but a list of aliases will not get expanded. For example, currently: mail -c "foo bar" christos will fail to send mail to 'foo' and 'bar' if these are mail aliases (in ~/.mailrc); sendmail aliases (in /etc/aliases) do work. 7) pipe command: This pipes the current message into a shell command. I use this for quick decoding of uuencoded mail, but I can imagine it might be useful for decrypting encrypted mail, too. 8) show command: This command takes a list of variables and shows their values. It is probably stupid as the 'set' command without any argument displays all variable values. Of course, if there are a lot of variables you have to sift through the list for the one(s) you want.
2006-09-18 23:46:21 +04:00
t = GTO|GSUBJECT|GCC|GNL|GSMOPTS;
1993-03-21 12:45:37 +03:00
getsub = 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 (hp->h_subject == NULL && value(ENAME_INTERACTIVE) != NULL &&
(value(ENAME_ASK) != NULL || value(ENAME_ASKSUB) != NULL))
1993-03-21 12:45:37 +03:00
t &= ~GNL, getsub++;
if (printheaders) {
2005-07-20 03:07:10 +04:00
(void)puthead(hp, stdout, t);
(void)fflush(stdout);
1993-03-21 12:45: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 ((cp = value(ENAME_ESCAPE)) != NULL)
1993-03-21 12:45:37 +03:00
escape = *cp;
else
escape = ESCAPE;
hadintr = 0; /* static - no longjmp problem */
1993-03-21 12:45:37 +03:00
if (!setjmp(colljmp)) {
if (getsub)
2005-07-20 03:07:10 +04:00
(void)grabh(hp, GSUBJECT);
1993-03-21 12:45:37 +03:00
} else {
/*
* Come here for printing the after-signal message.
* Duplicate messages won't be printed because
* the write is aborted if we get a SIGTTOU.
*/
cont:
if (hadintr) {
2005-07-20 03:07:10 +04:00
(void)fflush(stdout);
(void)fprintf(stderr,
1993-03-21 12:45:37 +03:00
"\n(Interrupt -- one more to kill letter)\n");
} else {
2005-07-20 03:07:10 +04:00
(void)printf("(continue)\n");
(void)fflush(stdout);
1993-03-21 12:45:37 +03:00
}
}
eofcount = 0; /* reset after possible longjmp */
longline = 0; /* reset after possible longjmp */
1993-03-21 12:45:37 +03:00
for (;;) {
colljmp_p = 1;
c = mail_readline(stdin, linebuf, LINESIZE);
1993-03-21 12:45:37 +03:00
colljmp_p = 0;
#ifdef USE_EDITLINE
Jumbo mail patch from our anonymous user: 1) Use editline [optional]: Most of this code was borrowed from src/usr.bin/ftp. It does the appropriate editing, history, and completion for all mail commands (from cmdtab[]) and also does editing on header strings ('~h' inside the mail editor). 2) '-B' flag: This will suppress the "To:" line passed to sendmail. In most configurations it will lead to sendmail adding "To: undisclosed recipients;". Currently, AFAIK mail requires at least one exposed recipient address. 3) Comments in rcfile: Currently, comments in .mailrc are only supported if the first (non-white) character on a line is '#' followed by white space, i.e., '#' is a 'nop' command. This (trivial) patch allows the more normal/expected use of '#' as a comment character. It does not respect quoting, so that might be an objection which I should fix. 4) Sendmail option editing: This adds the sendmail option string to the strings editable by the '~h' command within the mail editor. Currently, you can only set this string from the command-line, which is particularly annoying when replying to mail. 5) Reply from: When replying to a message, grab the "To:" address from the message and, if there is only one such address and it does not match a list of allowed addresses (set in the "ReplyFrom" variable), pass it to sendmail as the "From:" address for the reply (with the '-f' option). I often make aliases for myself so that my primary address is not given out; if the alias gets out, I know who to blame. Unfortunately, a reply to such a message would normally use the primary address without this patch. A warning is displayed when this is going to happen so that it can be modified with '~h'. 6) CC and BCC lists: Allow '-c' and '-b' to accept white-space or ',' delimited lists. Currently, a white-space delimited list of addresses work, but a list of aliases will not get expanded. For example, currently: mail -c "foo bar" christos will fail to send mail to 'foo' and 'bar' if these are mail aliases (in ~/.mailrc); sendmail aliases (in /etc/aliases) do work. 7) pipe command: This pipes the current message into a shell command. I use this for quick decoding of uuencoded mail, but I can imagine it might be useful for decrypting encrypted mail, too. 8) show command: This command takes a list of variables and shows their values. It is probably stupid as the 'set' command without any argument displays all variable values. Of course, if there are a lot of variables you have to sift through the list for the one(s) you want.
2006-09-18 23:46:21 +04:00
if (c < 0) {
char *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 (value(ENAME_INTERACTIVE) != NULL &&
(p = value(ENAME_IGNOREEOF)) != NULL &&
Jumbo mail patch from our anonymous user: 1) Use editline [optional]: Most of this code was borrowed from src/usr.bin/ftp. It does the appropriate editing, history, and completion for all mail commands (from cmdtab[]) and also does editing on header strings ('~h' inside the mail editor). 2) '-B' flag: This will suppress the "To:" line passed to sendmail. In most configurations it will lead to sendmail adding "To: undisclosed recipients;". Currently, AFAIK mail requires at least one exposed recipient address. 3) Comments in rcfile: Currently, comments in .mailrc are only supported if the first (non-white) character on a line is '#' followed by white space, i.e., '#' is a 'nop' command. This (trivial) patch allows the more normal/expected use of '#' as a comment character. It does not respect quoting, so that might be an objection which I should fix. 4) Sendmail option editing: This adds the sendmail option string to the strings editable by the '~h' command within the mail editor. Currently, you can only set this string from the command-line, which is particularly annoying when replying to mail. 5) Reply from: When replying to a message, grab the "To:" address from the message and, if there is only one such address and it does not match a list of allowed addresses (set in the "ReplyFrom" variable), pass it to sendmail as the "From:" address for the reply (with the '-f' option). I often make aliases for myself so that my primary address is not given out; if the alias gets out, I know who to blame. Unfortunately, a reply to such a message would normally use the primary address without this patch. A warning is displayed when this is going to happen so that it can be modified with '~h'. 6) CC and BCC lists: Allow '-c' and '-b' to accept white-space or ',' delimited lists. Currently, a white-space delimited list of addresses work, but a list of aliases will not get expanded. For example, currently: mail -c "foo bar" christos will fail to send mail to 'foo' and 'bar' if these are mail aliases (in ~/.mailrc); sendmail aliases (in /etc/aliases) do work. 7) pipe command: This pipes the current message into a shell command. I use this for quick decoding of uuencoded mail, but I can imagine it might be useful for decrypting encrypted mail, too. 8) show command: This command takes a list of variables and shows their values. It is probably stupid as the 'set' command without any argument displays all variable values. Of course, if there are a lot of variables you have to sift through the list for the one(s) you want.
2006-09-18 23:46:21 +04:00
++eofcount < (*p == 0 ? 25 : atoi(p))) {
(void)printf("Use \".\" to terminate letter\n");
continue;
}
break;
}
#else
1993-03-21 12:45:37 +03:00
if (c < 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 (value(ENAME_INTERACTIVE) != NULL &&
value(ENAME_IGNOREEOF) != NULL && ++eofcount < 25) {
2005-07-20 03:07:10 +04:00
(void)printf("Use \".\" to terminate letter\n");
1993-03-21 12:45:37 +03:00
continue;
}
break;
}
Jumbo mail patch from our anonymous user: 1) Use editline [optional]: Most of this code was borrowed from src/usr.bin/ftp. It does the appropriate editing, history, and completion for all mail commands (from cmdtab[]) and also does editing on header strings ('~h' inside the mail editor). 2) '-B' flag: This will suppress the "To:" line passed to sendmail. In most configurations it will lead to sendmail adding "To: undisclosed recipients;". Currently, AFAIK mail requires at least one exposed recipient address. 3) Comments in rcfile: Currently, comments in .mailrc are only supported if the first (non-white) character on a line is '#' followed by white space, i.e., '#' is a 'nop' command. This (trivial) patch allows the more normal/expected use of '#' as a comment character. It does not respect quoting, so that might be an objection which I should fix. 4) Sendmail option editing: This adds the sendmail option string to the strings editable by the '~h' command within the mail editor. Currently, you can only set this string from the command-line, which is particularly annoying when replying to mail. 5) Reply from: When replying to a message, grab the "To:" address from the message and, if there is only one such address and it does not match a list of allowed addresses (set in the "ReplyFrom" variable), pass it to sendmail as the "From:" address for the reply (with the '-f' option). I often make aliases for myself so that my primary address is not given out; if the alias gets out, I know who to blame. Unfortunately, a reply to such a message would normally use the primary address without this patch. A warning is displayed when this is going to happen so that it can be modified with '~h'. 6) CC and BCC lists: Allow '-c' and '-b' to accept white-space or ',' delimited lists. Currently, a white-space delimited list of addresses work, but a list of aliases will not get expanded. For example, currently: mail -c "foo bar" christos will fail to send mail to 'foo' and 'bar' if these are mail aliases (in ~/.mailrc); sendmail aliases (in /etc/aliases) do work. 7) pipe command: This pipes the current message into a shell command. I use this for quick decoding of uuencoded mail, but I can imagine it might be useful for decrypting encrypted mail, too. 8) show command: This command takes a list of variables and shows their values. It is probably stupid as the 'set' command without any argument displays all variable values. Of course, if there are a lot of variables you have to sift through the list for the one(s) you want.
2006-09-18 23:46:21 +04:00
#endif
lastlong = longline;
longline = c == LINESIZE-1;
1993-03-21 12:45:37 +03:00
eofcount = 0;
hadintr = 0;
if (linebuf[0] == '.' && linebuf[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
value(ENAME_INTERACTIVE) != NULL && !lastlong &&
(value(ENAME_DOT) != NULL || value(ENAME_IGNOREEOF) != NULL))
1993-03-21 12:45:37 +03:00
break;
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 (linebuf[0] != escape || value(ENAME_INTERACTIVE) == NULL ||
lastlong) {
if (putline(collf, linebuf, !longline) < 0)
1993-03-21 12:45:37 +03:00
goto err;
continue;
}
c = linebuf[1];
switch (c) {
default:
/*
* On double escape, just send the single one.
* Otherwise, it's an error.
*/
if (c == escape) {
if (putline(collf, &linebuf[1], !longline) < 0)
1993-03-21 12:45:37 +03:00
goto err;
else
break;
}
2005-07-20 03:07:10 +04:00
(void)printf("Unknown tilde escape.\n");
1993-03-21 12:45:37 +03:00
break;
#ifdef MIME_SUPPORT
case '@':
hp->h_attach = mime_attach_files(hp->h_attach, &linebuf[2]);
break;
#endif
1993-03-21 12:45:37 +03:00
case 'C':
/*
* Dump core.
*/
2005-07-20 03:07:10 +04:00
(void)core(NULL);
1993-03-21 12:45:37 +03:00
break;
case '!':
/*
* Shell escape, send the balance of the
* line to sh -c.
*/
2005-07-20 03:07:10 +04:00
(void)shell(&linebuf[2]);
1993-03-21 12:45:37 +03:00
break;
case ':':
case '_':
1993-03-21 12:45:37 +03:00
/*
* Escape to command mode, but be nice!
*/
2005-07-20 03:07:10 +04:00
(void)execute(&linebuf[2], 1);
1993-03-21 12:45:37 +03:00
goto cont;
case '.':
/*
* Simulate end of file on input.
*/
goto out;
case 'q':
/*
* Force a quit of sending mail.
* Act like an interrupt happened.
*/
hadintr++;
collint(SIGINT);
exit(1);
2005-07-20 03:07:10 +04:00
/*NOTREACHED*/
case 'x': /* exit, do not save in dead.letter */
goto err;
1993-03-21 12:45:37 +03:00
case 'h':
/*
* Grab a bunch of headers.
*/
Jumbo mail patch from our anonymous user: 1) Use editline [optional]: Most of this code was borrowed from src/usr.bin/ftp. It does the appropriate editing, history, and completion for all mail commands (from cmdtab[]) and also does editing on header strings ('~h' inside the mail editor). 2) '-B' flag: This will suppress the "To:" line passed to sendmail. In most configurations it will lead to sendmail adding "To: undisclosed recipients;". Currently, AFAIK mail requires at least one exposed recipient address. 3) Comments in rcfile: Currently, comments in .mailrc are only supported if the first (non-white) character on a line is '#' followed by white space, i.e., '#' is a 'nop' command. This (trivial) patch allows the more normal/expected use of '#' as a comment character. It does not respect quoting, so that might be an objection which I should fix. 4) Sendmail option editing: This adds the sendmail option string to the strings editable by the '~h' command within the mail editor. Currently, you can only set this string from the command-line, which is particularly annoying when replying to mail. 5) Reply from: When replying to a message, grab the "To:" address from the message and, if there is only one such address and it does not match a list of allowed addresses (set in the "ReplyFrom" variable), pass it to sendmail as the "From:" address for the reply (with the '-f' option). I often make aliases for myself so that my primary address is not given out; if the alias gets out, I know who to blame. Unfortunately, a reply to such a message would normally use the primary address without this patch. A warning is displayed when this is going to happen so that it can be modified with '~h'. 6) CC and BCC lists: Allow '-c' and '-b' to accept white-space or ',' delimited lists. Currently, a white-space delimited list of addresses work, but a list of aliases will not get expanded. For example, currently: mail -c "foo bar" christos will fail to send mail to 'foo' and 'bar' if these are mail aliases (in ~/.mailrc); sendmail aliases (in /etc/aliases) do work. 7) pipe command: This pipes the current message into a shell command. I use this for quick decoding of uuencoded mail, but I can imagine it might be useful for decrypting encrypted mail, too. 8) show command: This command takes a list of variables and shows their values. It is probably stupid as the 'set' command without any argument displays all variable values. Of course, if there are a lot of variables you have to sift through the list for the one(s) you want.
2006-09-18 23:46:21 +04:00
(void)grabh(hp, GTO|GSUBJECT|GCC|GBCC|GSMOPTS);
1993-03-21 12:45:37 +03:00
goto cont;
case 't':
/*
* Add to the To list.
*/
hp->h_to = cat(hp->h_to, extract(&linebuf[2], GTO));
break;
case 's':
/*
* Set the Subject list.
*/
cp = &linebuf[2];
1998-12-19 19:31:57 +03:00
while (isspace((unsigned char)*cp))
1993-03-21 12:45:37 +03:00
cp++;
hp->h_subject = savestr(cp);
break;
case 'c':
/*
* Add to the CC list.
*/
hp->h_cc = cat(hp->h_cc, extract(&linebuf[2], GCC));
break;
case 'b':
/*
* Add stuff to blind carbon copies list.
*/
hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC));
break;
case 'i':
case 'A':
case 'a':
/*
* Insert named variable in message
*/
switch(c) {
case 'i':
cp = &linebuf[2];
while(isspace((unsigned char) *cp))
cp++;
break;
case 'a':
cp = "sign";
break;
case 'A':
cp = "Sign";
break;
default:
goto err;
}
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 (*cp && (cp = value(cp)) != NULL) {
2005-07-20 03:07:10 +04:00
(void)printf("%s\n", cp);
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 (putline(collf, cp, 1) < 0)
goto err;
}
break;
1993-03-21 12:45:37 +03:00
case 'd':
2005-07-20 03:07:10 +04:00
(void)strcpy(linebuf + 2, getdeadletter());
/* FALLTHROUGH */
1993-03-21 12:45:37 +03:00
case 'r':
case '<':
1993-03-21 12:45:37 +03:00
/*
* Invoke a file:
* Search for the file name,
* then open it and copy the contents to collf.
*/
cp = &linebuf[2];
1998-12-19 19:31:57 +03:00
while (isspace((unsigned char)*cp))
1993-03-21 12:45:37 +03:00
cp++;
if (*cp == '\0') {
2005-07-20 03:07:10 +04:00
(void)printf("Interpolate what file?\n");
1993-03-21 12:45:37 +03:00
break;
}
1993-03-21 12:45:37 +03:00
cp = expand(cp);
if (cp == NULL)
1993-03-21 12:45:37 +03:00
break;
if (*cp == '!') { /* insert stdout of command */
2005-07-19 05:38:38 +04:00
const char *shellcmd;
int nullfd;
2002-03-02 18:27:51 +03:00
int rc2;
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 ((nullfd = open("/dev/null", O_RDONLY, 0)) == -1) {
2002-03-06 00:29:30 +03:00
warn("/dev/null");
break;
}
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.ReXXXXXXXXXX", tmpdir);
if ((fd = mkstemp(tempname)) == -1 ||
(fbuf = Fdopen(fd, "w+")) == NULL) {
if (fd != -1)
2005-07-20 03:07:10 +04:00
(void)close(fd);
warn("%s", tempname);
break;
}
(void)unlink(tempname);
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 ((shellcmd = value(ENAME_SHELL)) == NULL)
2002-03-02 18:27:51 +03:00
shellcmd = _PATH_CSHELL;
rc2 = run_command(shellcmd, 0, nullfd, fileno(fbuf), "-c", cp + 1, NULL);
2005-07-20 03:07:10 +04:00
(void)close(nullfd);
2002-03-02 18:27:51 +03:00
if (rc2 < 0) {
2002-03-06 00:18:14 +03:00
(void)Fclose(fbuf);
break;
}
if (fsize(fbuf) == 0) {
(void)fprintf(stderr, "No bytes from command \"%s\"\n", cp + 1);
2002-03-06 00:18:14 +03:00
(void)Fclose(fbuf);
break;
}
rewind(fbuf);
}
else if (isdir(cp)) {
2005-07-20 03:07:10 +04:00
(void)printf("%s: Directory\n", cp);
1993-03-21 12:45:37 +03:00
break;
}
else if ((fbuf = Fopen(cp, "r")) == NULL) {
2002-03-06 00:29:30 +03:00
warn("%s", cp);
1993-03-21 12:45:37 +03:00
break;
}
2005-07-20 03:07:10 +04:00
(void)printf("\"%s\" ", cp);
(void)fflush(stdout);
1993-03-21 12:45:37 +03:00
lc = 0;
cc = 0;
while ((rc = mail_readline(fbuf, linebuf, LINESIZE)) >= 0) {
if (rc != LINESIZE-1) lc++;
if ((t = putline(collf, linebuf,
rc != LINESIZE-1)) < 0) {
2005-07-20 03:07:10 +04:00
(void)Fclose(fbuf);
1993-03-21 12:45:37 +03:00
goto err;
}
cc += t;
}
2005-07-20 03:07:10 +04:00
(void)Fclose(fbuf);
(void)printf("%d/%d\n", lc, cc);
1993-03-21 12:45:37 +03:00
break;
case 'w':
/*
* Write the message on a file.
*/
cp = &linebuf[2];
while (*cp == ' ' || *cp == '\t')
cp++;
if (*cp == '\0') {
2005-07-20 03:07:10 +04:00
(void)fprintf(stderr, "Write what file!?\n");
1993-03-21 12:45:37 +03:00
break;
}
if ((cp = expand(cp)) == NULL)
1993-03-21 12:45:37 +03:00
break;
rewind(collf);
2005-07-20 03:07:10 +04:00
(void)exwrite(cp, collf, 1);
1993-03-21 12:45:37 +03:00
break;
case 'm':
case 'M':
case 'f':
case 'F':
/*
* Interpolate the named messages, if we
* are in receiving mail mode. Does the
* standard list processing garbage.
* If ~f is given, we don't shift over.
*/
if (forward(linebuf + 2, collf, mailtempname, c) < 0)
1993-03-21 12:45:37 +03:00
goto err;
goto cont;
case '?':
if ((fbuf = Fopen(_PATH_TILDE, "r")) == NULL) {
2002-03-06 00:29:30 +03:00
warn(_PATH_TILDE);
1993-03-21 12:45:37 +03:00
break;
}
while ((t = getc(fbuf)) != EOF)
2002-03-06 00:18:14 +03:00
(void)putchar(t);
2005-07-20 03:07:10 +04:00
(void)Fclose(fbuf);
1993-03-21 12:45:37 +03:00
break;
case 'p':
/*
* Print out the current state of the
* message without altering anything.
*/
rewind(collf);
2005-07-20 03:07:10 +04:00
(void)printf("-------\nMessage contains:\n");
(void)puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
1993-03-21 12:45:37 +03:00
while ((t = getc(collf)) != EOF)
2002-03-06 00:18:14 +03:00
(void)putchar(t);
1993-03-21 12:45:37 +03:00
goto cont;
case '|':
/*
* Pipe message through command.
* Collect output as new message.
*/
rewind(collf);
mespipe(collf, &linebuf[2]);
goto cont;
case 'v':
case 'e':
/*
* Edit the current message.
* 'e' means to use EDITOR
* 'v' means to use VISUAL
*/
rewind(collf);
mesedit(collf, c);
goto cont;
}
}
goto out;
err:
if (collf != NULL) {
2005-07-20 03:07:10 +04:00
(void)Fclose(collf);
1993-03-21 12:45:37 +03:00
collf = NULL;
}
out:
if (collf != NULL)
rewind(collf);
noreset--;
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
2005-07-20 03:07:10 +04:00
(void)signal(SIGINT, saveint);
(void)signal(SIGHUP, savehup);
(void)signal(SIGTSTP, savetstp);
(void)signal(SIGTTOU, savettou);
(void)signal(SIGTTIN, savettin);
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
1993-03-21 12:45:37 +03:00
return collf;
}