summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2019-09-03 14:47:14 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-09-03 14:50:54 (GMT)
commit016c4a978a69cc8990b5aab6c88cbac6fda57203 (patch) (side-by-side diff)
treef451622ce35a0b64e52522aeef82bd3064faef06
parentddfa689bff19d877170add6fed3381f3d5b79a8e (diff)
downloadmailutils-016c4a978a69cc8990b5aab6c88cbac6fda57203.tar.gz
mailutils-016c4a978a69cc8990b5aab6c88cbac6fda57203.tar.bz2
comsatd: optional argument to the --test option supplies the name of the tty to use
* NEWS: Document changes. * comsat/action.c (open_default_tty): Remove. (open_tty): Examine the tty device (or file) and construct a suitable filter chain. Use append mode when opening it. * comsat/comsat.c: The --test option takes optional argument. * comsat/tests/testsuite.at: Use local file instead of the tty. * doc/texinfo/programs/comsatd.texi: Document changes.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS7
-rw-r--r--comsat/action.c156
-rw-r--r--comsat/comsat.c32
-rw-r--r--comsat/tests/testsuite.at62
-rw-r--r--doc/texinfo/programs/comsatd.texi28
5 files changed, 153 insertions, 132 deletions
diff --git a/NEWS b/NEWS
index 251f5a8..50eadb8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2019-08-29
+GNU mailutils NEWS -- history of user-visible changes. 2019-09-03
Copyright (C) 2002-2019 Free Software Foundation, Inc.
See the end of file for copying conditions.
@@ -23,6 +23,11 @@ Example configuration (pop3s server):
ssl-certificate-file /etc/ssl/cert.pem;
}
+* comsatd --test
+
+The --test option takes optional argument: name of the tty or file to
+use for reporting.
+
Version 3.7 - 2019-06-21
diff --git a/comsat/action.c b/comsat/action.c
index c9703f2..b6799c4 100644
--- a/comsat/action.c
+++ b/comsat/action.c
@@ -176,32 +176,78 @@ const char *default_action =
#include "biff.rc.h"
;
+/* Examine the tty to determine which filters to apply when printing
+ to it. On entry, STR is the opened stream, FLT points to an array
+ of char* with at least 3 slots, and NFLT to an integer number.
+ On success, populates FLT with the necessary filter chain, and stores
+ to *NFLT the number of used slots. On error, issues error message and
+ returns -1.
+ FLT and NFLT can be used as input to mu_filter_chain_create.
+ */
static int
-need_crlf (mu_stream_t str)
+study_tty (mu_stream_t str, char *flt[], int *nflt)
{
-#if defined(OPOST) && defined(ONLCR)
mu_transport_t trans[2];
- struct termios tbuf;
+ int fd;
+ struct stat st;
+ int rc;
- if (mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans))
- return 1; /* suppose we do need it */
- if (tcgetattr ((int) (intptr_t) trans[0], &tbuf) == 0 &&
- (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR))
- return 0;
- else
- return 1;
+ rc = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans);
+ if (rc)
+ {
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_ioctl", NULL, rc);
+ return rc;
+ }
+
+ *nflt = 0;
+ fd = (int) (intptr_t) trans[0];
+ if (fstat (fd, &st) == 0)
+ {
+ switch (st.st_mode & S_IFMT)
+ {
+ case S_IFREG:
+ return 0;
+
+ case S_IFCHR:
+ flt[(*nflt)++] = "7BIT";
+#if defined(OPOST) && defined(ONLCR)
+ {
+ struct termios tbuf;
+
+ if (!(tcgetattr (fd, &tbuf) == 0
+ && (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)))
+ {
+ flt[(*nflt)++] = "+";
+ flt[(*nflt)++] = "CRLF";
+ }
+ }
#else
- return 1; /* Just in case */
+ /* Just in case */
+ flt[(*nflt)++] = "+";
+ flt[(*nflt)++] = "CRLF";
#endif
+ break;
+
+ case S_IFSOCK:
+ return 0;
+
+ default:
+ /* FIXME: Perhaps an error? */
+ return 0;
+ }
+ }
+
+ return 0;
}
static mu_stream_t
_open_tty (const char *device, int argc, char **argv)
{
- mu_stream_t dev, base_dev, prev_stream;
+ mu_stream_t dev;
int status;
+ char *dfl_argv[4];
- status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE);
+ status = mu_file_stream_create (&dev, device, MU_STREAM_APPEND|MU_STREAM_CREAT);
if (status)
{
mu_error (_("cannot open device %s: %s"),
@@ -210,58 +256,28 @@ _open_tty (const char *device, int argc, char **argv)
}
mu_stream_set_buffer (dev, mu_buffer_line, 0);
- prev_stream = base_dev = dev;
- while (argc)
+ if (argc == 0)
{
- int i;
- int mode;
- int qmark;
- char *fltname;
-
- fltname = argv[0];
- if (fltname[0] == '?')
- {
- qmark = 1;
- fltname++;
- }
- else
- qmark = 0;
-
- if (fltname[0] == '~')
- {
- mode = MU_FILTER_DECODE;
- fltname++;
- }
- else
- {
- mode = MU_FILTER_ENCODE;
- }
-
- for (i = 1; i < argc; i++)
- if (strcmp (argv[i], "+") == 0)
- break;
-
- if (qmark == 0 || need_crlf (base_dev))
- {
- status = mu_filter_create_args (&dev, prev_stream, fltname,
- i, (const char **)argv,
- mode, MU_STREAM_WRITE);
- mu_stream_unref (prev_stream);
- if (status)
- {
- mu_error (_("cannot open filter stream: %s"),
- mu_strerror (status));
- return NULL;
- }
- prev_stream = dev;
- }
- argc -= i;
- argv += i;
- if (argc)
+ status = study_tty (dev, dfl_argv, &argc);
+ if (status)
+ return NULL;
+ argv = dfl_argv;
+ }
+
+ if (argc)
+ {
+ mu_stream_t str;
+ status = mu_filter_chain_create (&str, dev,
+ MU_FILTER_ENCODE, MU_STREAM_WRITE,
+ argc, argv);
+ mu_stream_unref (dev);
+ if (status)
{
- argc--;
- argv++;
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_chain_create", device,
+ status);
+ return NULL;
}
+ dev = str;
}
return dev;
}
@@ -275,21 +291,15 @@ open_tty (const char *device, int argc, char **argv)
{
int rc = mu_nullstream_create (&dev, MU_STREAM_WRITE);
if (rc)
- mu_error (_("cannot open null stream: %s"), mu_strerror (rc));
+ {
+ mu_error (_("cannot open null stream: %s"), mu_strerror (rc));
+ dev = NULL;
+ }
}
else
dev = _open_tty (device, argc, argv);
return dev;
}
-
-static mu_stream_t
-open_default_tty (const char *device)
-{
- static char *default_filters[] = { "7bit", "+", "?CRLF", NULL };
- return open_tty (device, MU_ARRAY_SIZE (default_filters) - 1,
- default_filters);
-}
-
struct biffrc_environ
{
@@ -611,7 +621,7 @@ run_user_action (const char *device, mu_message_t msg)
mu_stream_t stream;
struct biffrc_environ env;
- env.tty = open_default_tty (device);
+ env.tty = open_tty (device, 0, NULL);
if (!env.tty)
return;
env.msg = msg;
diff --git a/comsat/comsat.c b/comsat/comsat.c
index f317fa6..cee4745 100644
--- a/comsat/comsat.c
+++ b/comsat/comsat.c
@@ -18,6 +18,7 @@
#include "mailutils/syslog.h"
#include "mailutils/cli.h"
#include "mailutils/sockaddr.h"
+#include "mailutils/alloc.h"
#ifndef PATH_DEV
# define PATH_DEV "/dev"
@@ -59,7 +60,7 @@ typedef struct utmp UTMP;
const char *program_version = "comsatd (" PACKAGE_STRING ")";
-int test_mode;
+char *test_mode;
char *biffrc = BIFF_RC;
mu_m_server_t server;
@@ -69,7 +70,26 @@ set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt,
{
mu_m_server_set_mode (server, MODE_INTERACTIVE);
}
-
+
+static void
+set_test_mode (struct mu_parseopt *po, struct mu_option *opt,
+ char const *arg)
+{
+ if (arg)
+ {
+ if (arg[0] != '/')
+ {
+ test_mode = mu_make_file_name (mu_getcwd (), arg);
+ if (!test_mode)
+ mu_alloc_die ();
+ }
+ else
+ test_mode = mu_strdup (arg);
+ }
+ else
+ test_mode = mu_strdup ("/dev/tty");
+}
+
static void
set_daemon_mode (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
@@ -97,9 +117,9 @@ set_foreground (struct mu_parseopt *po, struct mu_option *opt,
}
static struct mu_option comsat_options[] = {
- { "test", 't', NULL, MU_OPTION_DEFAULT,
- N_("run in test mode"),
- mu_c_bool, &test_mode },
+ { "test", 't', N_("FILE"), MU_OPTION_ARG_OPTIONAL,
+ N_("run in test mode; use FILE as tty (default: /dev/tty)"),
+ mu_c_string, &test_mode, set_test_mode },
{ "foreground", 0, NULL, MU_OPTION_DEFAULT,
N_("remain in foreground"),
mu_c_bool, NULL, set_foreground },
@@ -605,7 +625,7 @@ main (int argc, char **argv)
free (cwd);
}
- notify_user (user, "/dev/tty", argv[0], argv[1]);
+ notify_user (user, test_mode, argv[0], argv[1]);
exit (0);
}
diff --git a/comsat/tests/testsuite.at b/comsat/tests/testsuite.at
index 45f3b1e..db2dbd0 100644
--- a/comsat/tests/testsuite.at
+++ b/comsat/tests/testsuite.at
@@ -23,7 +23,7 @@ m4_pushdef([BIFF_MBOX],[`pwd`/mailbox])
dnl ------------------------------------------------------------
dnl comsatcmd
m4_pushdef([comsatcmd],[comsatd --no-site-config --file ./biff.rc dnl
- --set logging.syslog=no --test])
+ --set logging.syslog=no --test=output])
dnl ------------------------------------------------------------
dnl BIFFTEST(DESCR, KW, DATA, CMDLINE, [STDOUT = `'], [STDERR = `'])
@@ -34,8 +34,10 @@ dnl
m4_pushdef([BIFFTEST],[
AT_SETUP([comsatd: $1])
AT_KEYWORDS([comsatd $2])
+AT_CHECK([test -w / && AT_SKIP_TEST
+cwd=`pwd`
$3
-AT_CHECK([test -w / && AT_SKIP_TEST; $4],[0],[$5],[$6])
+],[0],[$4],[$5])
AT_CLEANUP])
AT_INIT
@@ -45,16 +47,9 @@ AT_TESTED([comsatd])
MUT_VERSION(comsatd)
BIFFTEST([default commands],[comsatd00],
-[cwd=`pwd`
+[
MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox)
-cat > biff.rc <<EOT
-tty $cwd/output
-default
-EOT
-chmod 600 biff.rc
-> $cwd/output
-],
-[comsatcmd $cwd/mailbox 0
+comsatcmd $cwd/mailbox 0
sed '1s/^Mail to .*/Mail to test user/' output
],
[Mail to test user
@@ -69,16 +64,9 @@ Have some wine
])
BIFFTEST([non-zero qid],[comsatd01],
-[cwd=`pwd`
+[
MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox)
-cat > biff.rc <<EOT
-tty $cwd/output
-default
-EOT
-chmod 600 biff.rc
-> $cwd/output
-],
-[comsatcmd $cwd/mailbox 9367
+comsatcmd $cwd/mailbox 9367
sed '1s/^Mail to .*/Mail to test user/' output
],
[Mail to test user
@@ -94,16 +82,9 @@ month, and doesn't tell what o'clock it is!
])
BIFFTEST([maildir qid],[comsatd02],
-[cwd=`pwd`
+[
MUT_MBCOPY($abs_top_srcdir/testsuite/maildir/teaparty, mailbox)
-cat > biff.rc <<EOT
-tty $cwd/output
-default
-EOT
-chmod 600 biff.rc
-> $cwd/output
-],
-[test "$MAILDIR_SUPPORT" = yes || AT_SKIP_TEST
+test "$MAILDIR_SUPPORT" = yes || AT_SKIP_TEST
comsatcmd maildir:$cwd/mailbox new/1284627340.M364969P3770Q81.Trurl
sed '1s/^Mail to .*/Mail to test user/' output
],
@@ -119,16 +100,9 @@ What did they draw?
BIFFTEST([MH qid],[comsatd03],
-[cwd=`pwd`
+[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty, mailbox)
-cat > biff.rc <<EOT
-tty $cwd/output
-default
-EOT
-chmod 600 biff.rc
-> $cwd/output
-],
-[test "$MH_SUPPORT" = yes || AT_SKIP_TEST
+test "$MH_SUPPORT" = yes || AT_SKIP_TEST
comsatcmd mh:$cwd/mailbox teaparty/58
sed '1s/^Mail to .*/Mail to test user/' output
],
@@ -144,16 +118,13 @@ I vote the young lady tells us a story.
])
BIFFTEST([beep command],[comsatd04],
-[cwd=`pwd`
+[
MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox1, mailbox)
cat > biff.rc <<EOT
-tty $cwd/output
beep
EOT
chmod 600 biff.rc
-> $cwd/output
-],
-[comsatcmd $cwd/mailbox 0
+comsatcmd $cwd/mailbox 0
cat output | tr '\a' A
],
[AA])
@@ -166,13 +137,10 @@ echo "You have mail from $1, regarding $2"
])
chmod +x notifier
cat > biff.rc <<EOT
-tty $cwd/output
exec $cwd/notifier '\$H{from}' '\$H{Subject}'
EOT
chmod 600 biff.rc
-> $cwd/output
-],
-[comsatcmd $cwd/mailbox 0
+comsatcmd $cwd/mailbox 0
cat output
],
[You have mail from March Hare <hare@wonder.land>, regarding Invitation
diff --git a/doc/texinfo/programs/comsatd.texi b/doc/texinfo/programs/comsatd.texi
index 15cbd3d..07fa516 100644
--- a/doc/texinfo/programs/comsatd.texi
+++ b/doc/texinfo/programs/comsatd.texi
@@ -5,8 +5,9 @@
@pindex comsatd
Comsatd is the server which receives reports of incoming mail and
-notifies users, wishing to get this service. It can be started
-either from @file{inetd.conf} or as a standalone daemon.
+notifies users about it. By default, it prints subject, sender
+name and email, followed by first five lines of each newly arrived message
+to the tty of the recipient user. Users can customize this behavior.
@menu
* Starting comsatd:: Invocation.
@@ -33,16 +34,33 @@ comsatd -c /etc/comsat.conf
This is the default operation mode.
-@item -t
-@itemx --test
+@item -t[@var{file}]
+@itemx --test[=@var{file}]
Test mode. In this mode, @command{comsatd} takes two arguments:
@acronym{URL} of a mailbox and @acronym{QID} of the message from that
-mailbox, e.g.:
+mailbox and prints the notification to the current user tty
+(@file{/dev/tty}), or @var{file}, if it is supplied. If the
+@file{~/.biffrc} file exists, it will be used. For example:
@example
$ comsatd --test /var/mail/root 34589
@end example
+Notice, that @var{file} is an optional argument. When supplied, it
+should follow the short option form immediately, or the long option
+form after the equals sign, e.g.:
+
+@example
+$ comsatd --test=logfile /var/mail/root 34589
+@end example
+
+@noindent
+or
+
+@example
+$ comsatd -tlogfile /var/mail/root 34589
+@end example
+
@item --foreground
Don't detach from the controlling terminal, remain in foreground.
@end table

Return to:

Send suggestions and report system problems to the System administrator.