diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-09-03 17:47:14 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-09-03 17:50:54 +0300 |
commit | 016c4a978a69cc8990b5aab6c88cbac6fda57203 (patch) | |
tree | f451622ce35a0b64e52522aeef82bd3064faef06 | |
parent | ddfa689bff19d877170add6fed3381f3d5b79a8e (diff) | |
download | mailutils-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.
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | comsat/action.c | 142 | ||||
-rw-r--r-- | comsat/comsat.c | 30 | ||||
-rw-r--r-- | comsat/tests/testsuite.at | 62 | ||||
-rw-r--r-- | doc/texinfo/programs/comsatd.texi | 28 |
5 files changed, 145 insertions, 124 deletions
@@ -1,7 +1,7 @@ -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. Please send mailutils bug reports to <bug-mailutils@gnu.org>. Version 3.7.90 (git) @@ -20,12 +20,17 @@ Example configuration (pop3s server): tls-mode connection; tls { ssl-key-file /etc/ssl/key.pem; 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 * Support for the new mailbox format - dotmail Dotmail is a replacement for traditional mbox format, proposed by diff --git a/comsat/action.c b/comsat/action.c index c9703f28e..b6799c481 100644 --- a/comsat/action.c +++ b/comsat/action.c @@ -173,98 +173,114 @@ expand_line (const char *str, mu_message_t msg) } 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; + + 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; + } - 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)) + *nflt = 0; + fd = (int) (intptr_t) trans[0]; + if (fstat (fd, &st) == 0) + { + switch (st.st_mode & S_IFMT) + { + case S_IFREG: return 0; - else - return 1; + + 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"), device, mu_strerror (status)); return NULL; } mu_stream_set_buffer (dev, mu_buffer_line, 0); - prev_stream = base_dev = dev; - while (argc) - { - int i; - int mode; - int qmark; - char *fltname; - - fltname = argv[0]; - if (fltname[0] == '?') - { - qmark = 1; - fltname++; - } - else - qmark = 0; - - if (fltname[0] == '~') + if (argc == 0) { - mode = MU_FILTER_DECODE; - fltname++; - } - else - { - mode = MU_FILTER_ENCODE; + status = study_tty (dev, dfl_argv, &argc); + if (status) + return NULL; + argv = dfl_argv; } - for (i = 1; i < argc; i++) - if (strcmp (argv[i], "+") == 0) - break; - - if (qmark == 0 || need_crlf (base_dev)) + if (argc) { - status = mu_filter_create_args (&dev, prev_stream, fltname, - i, (const char **)argv, - mode, MU_STREAM_WRITE); - mu_stream_unref (prev_stream); + 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) { - mu_error (_("cannot open filter stream: %s"), - mu_strerror (status)); + mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_chain_create", device, + status); return NULL; } - prev_stream = dev; - } - argc -= i; - argv += i; - if (argc) - { - argc--; - argv++; - } + dev = str; } return dev; } mu_stream_t open_tty (const char *device, int argc, char **argv) @@ -272,28 +288,22 @@ open_tty (const char *device, int argc, char **argv) mu_stream_t dev; if (!device || !*device || strcmp (device, "null") == 0) { int rc = mu_nullstream_create (&dev, MU_STREAM_WRITE); if (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 { mu_stream_t tty; mu_stream_t logstr; mu_message_t msg; mu_stream_t input; @@ -608,13 +618,13 @@ void run_user_action (const char *device, mu_message_t msg) { int rc, mode; 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; env.errbuf = NULL; env.errsize = 0; diff --git a/comsat/comsat.c b/comsat/comsat.c index f317fa698..cee474572 100644 --- a/comsat/comsat.c +++ b/comsat/comsat.c @@ -15,12 +15,13 @@ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ #include "comsat.h" #include "mailutils/syslog.h" #include "mailutils/cli.h" #include "mailutils/sockaddr.h" +#include "mailutils/alloc.h" #ifndef PATH_DEV # define PATH_DEV "/dev" #endif #ifndef PATH_TTY_PFX # define PATH_TTY_PFX PATH_DEV @@ -56,24 +57,43 @@ typedef struct utmp UTMP; #endif #define MAX_TTY_SIZE (sizeof (PATH_TTY_PFX) + sizeof (((UTMP*)0)->ut_line)) const char *program_version = "comsatd (" PACKAGE_STRING ")"; -int test_mode; +char *test_mode; char *biffrc = BIFF_RC; mu_m_server_t server; static void set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { 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) { mu_m_server_set_mode (server, MODE_DAEMON); if (arg) { @@ -94,15 +114,15 @@ set_foreground (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { mu_m_server_set_foreground (server, 1); } 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 }, { "inetd", 'i', NULL, MU_OPTION_DEFAULT, N_("run in inetd mode"), mu_c_bool, NULL, set_inetd_mode }, @@ -602,13 +622,13 @@ main (int argc, char **argv) exit (1); } mu_normalize_path (biffrc); free (cwd); } - notify_user (user, "/dev/tty", argv[0], argv[1]); + notify_user (user, test_mode, argv[0], argv[1]); exit (0); } mu_stdstream_strerr_setup (mu_log_syslog ? MU_STRERR_SYSLOG : MU_STRERR_STDERR); diff --git a/comsat/tests/testsuite.at b/comsat/tests/testsuite.at index 45f3b1e46..db2dbd02f 100644 --- a/comsat/tests/testsuite.at +++ b/comsat/tests/testsuite.at @@ -20,44 +20,39 @@ dnl ------------------------------------------------------------ dnl mailbox for comsatd 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 = `']) dnl dnl NOTE: The test is skipped if run as root, because .biffrc is dnl ignored for root (see open_rc() in action.c 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 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 --- From: March Hare <hare@wonder.land> Subject: Invitation @@ -66,22 +61,15 @@ 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 --- From: Alice <alice@wonder.land> Subject: Funny watch (was Re: Watch) @@ -91,22 +79,15 @@ 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 ], [Mail to test user --- From: Alice <alice@wonder.land> @@ -116,22 +97,15 @@ 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 ], [Mail to test user --- From: March Hare <hare@wonder.land> @@ -141,41 +115,35 @@ Suppose we change the subject, I'm getting tired of this. 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]) BIFFTEST([exec command],[comsatd05], [cwd=`pwd` MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox) AT_DATA([notifier],[#! /bin/sh 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 ]) m4_popdef([BIFFTEST]) diff --git a/doc/texinfo/programs/comsatd.texi b/doc/texinfo/programs/comsatd.texi index 15cbd3d0b..07fa516a0 100644 --- a/doc/texinfo/programs/comsatd.texi +++ b/doc/texinfo/programs/comsatd.texi @@ -2,14 +2,15 @@ @c Copyright (C) 1999-2019 Free Software Foundation, Inc. @c See file mailutils.texi for copying conditions. @comment ******************************************************************* @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. * Configuring comsatd:: Configuration of @command{comsatd}. * dot.biffrc:: A per-user configuration file. @end menu @@ -30,22 +31,39 @@ The server is started from @file{/etc/inetd.conf} file: comsat dgram udp wait root /usr/sbin/comsatd \ comsatd -c /etc/comsat.conf @end example 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 See also @ref{Common Options}. |