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,3 +1,3 @@ -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. @@ -24,4 +24,9 @@ Example configuration (pop3s server): } +* 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 c9703f28e..b6799c481 100644 --- a/comsat/action.c +++ b/comsat/action.c @@ -177,21 +177,66 @@ const char *default_action = ; +/* 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; } @@ -199,8 +244,9 @@ 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) { @@ -211,56 +257,26 @@ _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) - { - 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; @@ -276,5 +292,8 @@ 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)); + dev = NULL; + } } else @@ -283,13 +302,4 @@ open_tty (const char *device, int argc, char **argv) } -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 { @@ -612,5 +622,5 @@ run_user_action (const char *device, mu_message_t msg) struct biffrc_environ env; - env.tty = open_default_tty (device); + env.tty = open_tty (device, 0, NULL); if (!env.tty) return; diff --git a/comsat/comsat.c b/comsat/comsat.c index f317fa698..cee474572 100644 --- a/comsat/comsat.c +++ b/comsat/comsat.c @@ -19,4 +19,5 @@ #include "mailutils/cli.h" #include "mailutils/sockaddr.h" +#include "mailutils/alloc.h" #ifndef PATH_DEV @@ -60,5 +61,5 @@ 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; @@ -72,4 +73,23 @@ set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt, 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) @@ -98,7 +118,7 @@ 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"), @@ -606,5 +626,5 @@ main (int argc, char **argv) } - 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 45f3b1e46..db2dbd02f 100644 --- a/comsat/tests/testsuite.at +++ b/comsat/tests/testsuite.at @@ -24,5 +24,5 @@ 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 ------------------------------------------------------------ @@ -35,6 +35,8 @@ 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]) @@ -46,14 +48,7 @@ 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 ], @@ -70,14 +65,7 @@ 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 ], @@ -95,14 +83,7 @@ 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 @@ -120,14 +101,7 @@ 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 @@ -145,14 +119,11 @@ 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 ], @@ -167,11 +138,8 @@ 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 ], 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 @@ -6,6 +6,7 @@ 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 @@ -34,9 +35,11 @@ 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 @@ -44,4 +47,19 @@ $ 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. |