From 016c4a978a69cc8990b5aab6c88cbac6fda57203 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 3 Sep 2019 17:47:14 +0300 Subject: 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. --- comsat/action.c | 156 ++++++++++++++++++++++++---------------------- comsat/comsat.c | 32 ++++++++-- comsat/tests/testsuite.at | 62 +++++------------- 3 files changed, 124 insertions(+), 126 deletions(-) (limited to 'comsat') diff --git a/comsat/action.c b/comsat/action.c index c9703f28e..b6799c481 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 f317fa698..cee474572 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 45f3b1e46..db2dbd02f 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 < $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 < $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 < $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 < $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 < $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 < $cwd/output -], -[comsatcmd $cwd/mailbox 0 +comsatcmd $cwd/mailbox 0 cat output ], [You have mail from March Hare , regarding Invitation -- cgit v1.2.1