diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-12-08 11:27:14 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-12-08 12:07:27 +0200 |
commit | 835ee6b03a098d8566e9b9ba2c22ab2403d41cba (patch) | |
tree | f0e71e2e79014df29eeb32c1b513240d6ba46784 | |
parent | 2cbe825eb999f224ce756510dbd7123bc76ec924 (diff) | |
download | mailutils-835ee6b03a098d8566e9b9ba2c22ab2403d41cba.tar.gz mailutils-835ee6b03a098d8566e9b9ba2c22ab2403d41cba.tar.bz2 |
comsat: improve tty handling, add testsuite.
* comsat/action.c (need_crlf, _open_tty, open_tty): Moved from comsat.c
(open_default_tty): New function.
(run_user_action): Take device name as first argument.
Reuse wordsplit memory.
* comsat/comsat.c (notify_user): Update invocation of run_user_action.
* comsat/comsat.h (open_tty): Remove prototype.
(run_user_action): Change signature.
* configure.ac: Add comsat tests.
* comsat/Makefile.am (SUBDIRS): Add tests.
* comsat/tests/.gitignore: New file.
* comsat/tests/Makefile.am: New file.
* comsat/tests/atlocal.in: New file.
* comsat/tests/testsuite.at: New file.
-rw-r--r-- | comsat/Makefile.am | 2 | ||||
-rw-r--r-- | comsat/action.c | 136 | ||||
-rw-r--r-- | comsat/comsat.c | 117 | ||||
-rw-r--r-- | comsat/comsat.h | 3 | ||||
-rw-r--r-- | comsat/tests/.gitignore | 7 | ||||
-rw-r--r-- | comsat/tests/Makefile.am | 64 | ||||
-rw-r--r-- | comsat/tests/atlocal.in | 6 | ||||
-rw-r--r-- | comsat/tests/testsuite.at | 174 | ||||
-rw-r--r-- | configure.ac | 3 |
9 files changed, 386 insertions, 126 deletions
diff --git a/comsat/Makefile.am b/comsat/Makefile.am index 752aed37d..af34b3a8b 100644 --- a/comsat/Makefile.am +++ b/comsat/Makefile.am @@ -16,7 +16,7 @@ ## along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. INCLUDES = @MU_APP_COMMON_INCLUDES@ - +SUBDIRS = . tests sbin_PROGRAMS = comsatd comsatd_SOURCES = action.c comsat.c comsat.h diff --git a/comsat/action.c b/comsat/action.c index 46afde5e3..ab185c5fc 100644 --- a/comsat/action.c +++ b/comsat/action.c @@ -325,12 +325,129 @@ open_rc (const char *filename, mu_stream_t tty) return stream; } +static int +need_crlf (mu_stream_t str) +{ +#if defined(OPOST) && defined(ONLCR) + mu_transport_t trans[2]; + struct termios tbuf; + + if (mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans)) + return 1; /* suppose we do need it */ + if (tcgetattr ((int)trans[0], &tbuf) == 0 && + (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)) + return 0; + else + return 1; +#else + return 1; /* Just in case */ +#endif +} + +static mu_stream_t +_open_tty (const char *device, int argc, char **argv) +{ + mu_stream_t dev, base_dev, prev_stream; + int status; + + status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE); + 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] == '~') + { + 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) + { + argc--; + argv++; + } + } + return dev; +} + +mu_stream_t +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)); + } + 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); +} + void -run_user_action (mu_stream_t tty, mu_message_t msg) +run_user_action (const char *device, mu_message_t msg) { mu_stream_t input; int nact = 0; + mu_stream_t tty = open_default_tty (device); + if (!tty) + return; input = open_rc (biffrc, tty); if (input) { @@ -340,6 +457,8 @@ run_user_action (mu_stream_t tty, mu_message_t msg) char *cwd = mu_getcwd (); char *rcname; struct mu_locus locus; + struct mu_wordsplit ws; + int wsflags; rcname = mu_make_file_name (cwd, BIFF_RC); free (cwd); @@ -350,16 +469,15 @@ run_user_action (mu_stream_t tty, mu_message_t msg) } else locus.mu_file = rcname; + locus.mu_line = 1; locus.mu_col = 0; + + ws.ws_comment = "#"; + wsflags = MU_WRDSF_DEFFLAGS | MU_WRDSF_COMMENT; while (mu_stream_getline (input, &stmt, &size, &n) == 0 && n > 0) { - struct mu_wordsplit ws; - - ws.ws_comment = "#"; - if (mu_wordsplit (stmt, &ws, - MU_WRDSF_DEFFLAGS | MU_WRDSF_COMMENT) == 0 - && ws.ws_wordc) + if (mu_wordsplit (stmt, &ws, wsflags) == 0 && ws.ws_wordc) { mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus); @@ -428,11 +546,12 @@ run_user_action (mu_stream_t tty, mu_message_t msg) } } } - mu_wordsplit_free (&ws); + wsflags |= MU_WRDSF_REUSE; /* FIXME: line number is incorrect if .biffrc contains escaped newlines */ locus.mu_line++; } + mu_wordsplit_free (&ws); mu_stream_destroy (&input); mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); @@ -441,4 +560,5 @@ run_user_action (mu_stream_t tty, mu_message_t msg) if (nact == 0) echo_string (tty, expand_line (default_action, msg)); + mu_stream_destroy (&tty); } diff --git a/comsat/comsat.c b/comsat/comsat.c index c757bc46c..d16106c27 100644 --- a/comsat/comsat.c +++ b/comsat/comsat.c @@ -365,131 +365,19 @@ comsat_connection (int fd, struct sockaddr *sa, int salen, return 0; } -static int -need_crlf (mu_stream_t str) -{ -#if defined(OPOST) && defined(ONLCR) - mu_transport_t trans[2]; - struct termios tbuf; - - if (mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans)) - return 1; /* suppose we do need it */ - if (tcgetattr ((int)trans[0], &tbuf) == 0 && - (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)) - return 0; - else - return 1; -#else - return 1; /* Just in case */ -#endif -} - -static mu_stream_t -_open_tty (const char *device, int argc, char **argv) -{ - mu_stream_t dev, base_dev, prev_stream; - int status; - - status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE); - 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] == '~') - { - 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) - { - argc--; - argv++; - } - } - return dev; -} - -mu_stream_t -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)); - } - else - dev = _open_tty (device, argc, argv); - return dev; -} - /* NOTE: Do not bother to free allocated memory, as the program exits immediately after executing this */ static void notify_user (const char *user, const char *device, const char *path, mu_message_qid_t qid) { - mu_stream_t dev; mu_mailbox_t mbox = NULL; mu_message_t msg; - static char *default_filters[] = { "7bit", "+", "?CRLF", NULL }; int status; if (change_user (user)) return; - dev = open_tty (device, MU_ARRAY_SIZE (default_filters) - 1, - default_filters); - if (!dev) - return; if (!path) { path = mailbox_path (user); @@ -514,8 +402,7 @@ notify_user (const char *user, const char *device, const char *path, return; /* FIXME: Notify the user, anyway */ } - run_user_action (dev, msg); - mu_stream_destroy (&dev); + run_user_action (device, msg); } /* Search utmp for the local user */ @@ -683,7 +570,7 @@ main (int argc, char **argv) } } - if (biffrc[0] == '.') + if (biffrc[0] == '.' && biffrc[1] == '/') { char *cwd = mu_getcwd (); biffrc = mu_make_file_name (cwd, biffrc); diff --git a/comsat/comsat.h b/comsat/comsat.h index 8368c6ffc..ff4381933 100644 --- a/comsat/comsat.h +++ b/comsat/comsat.h @@ -79,6 +79,5 @@ extern char *hostname; extern struct daemon_param daemon_param; extern char *biffrc; -void run_user_action (mu_stream_t str, mu_message_t msg); -mu_stream_t open_tty (const char *device, int argc, char **argv); +void run_user_action (const char *device, mu_message_t msg); diff --git a/comsat/tests/.gitignore b/comsat/tests/.gitignore new file mode 100644 index 000000000..33e4e9a57 --- /dev/null +++ b/comsat/tests/.gitignore @@ -0,0 +1,7 @@ +atconfig +atlocal +package.m4 +status.mf +testsuite +testsuite.dir +testsuite.log diff --git a/comsat/tests/Makefile.am b/comsat/tests/Makefile.am new file mode 100644 index 000000000..cf77dbea0 --- /dev/null +++ b/comsat/tests/Makefile.am @@ -0,0 +1,64 @@ +# This file is part of GNU Mailutils. +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. + +EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 +DISTCLEANFILES = atconfig $(check_SCRIPTS) +MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE) + +## ------------ ## +## package.m4. ## +## ------------ ## + +$(srcdir)/package.m4: $(top_srcdir)/configure.ac + $(AM_V_GEN){ \ + echo '# Signature of the current package.'; \ + echo 'm4_define([AT_PACKAGE_NAME], [@PACKAGE_NAME@])'; \ + echo 'm4_define([AT_PACKAGE_TARNAME], [@PACKAGE_TARNAME@])'; \ + echo 'm4_define([AT_PACKAGE_VERSION], [@PACKAGE_VERSION@])'; \ + echo 'm4_define([AT_PACKAGE_STRING], [@PACKAGE_STRING@])'; \ + echo 'm4_define([AT_PACKAGE_BUGREPORT], [@PACKAGE_BUGREPORT@])'; \ + } >$(srcdir)/package.m4 + +# + +## ------------ ## +## Test suite. ## +## ------------ ## + +TESTSUITE_AT = testsuite.at + +TESTSUITE = $(srcdir)/testsuite +M4=m4 + +AUTOTEST = $(AUTOM4TE) --language=autotest +$(TESTSUITE): package.m4 $(TESTSUITE_AT) $(top_srcdir)/testsuite/testsuite.inc + $(AM_V_GEN)$(AUTOTEST) -I $(srcdir) -I $(top_srcdir)/testsuite testsuite.at -o $@.tmp + $(AM_V_at)mv $@.tmp $@ + +atconfig: $(top_builddir)/config.status + cd $(top_builddir) && ./config.status tests/$@ + +clean-local: + @test ! -f $(TESTSUITE) || $(SHELL) $(TESTSUITE) --clean + +check-local: atconfig atlocal $(TESTSUITE) + @$(SHELL) $(TESTSUITE) + +# Run the test suite on the *installed* tree. +#installcheck-local: +# $(SHELL) $(TESTSUITE) AUTOTEST_PATH=$(exec_prefix)/bin + + diff --git a/comsat/tests/atlocal.in b/comsat/tests/atlocal.in new file mode 100644 index 000000000..ba56b8807 --- /dev/null +++ b/comsat/tests/atlocal.in @@ -0,0 +1,6 @@ +# @configure_input@ -*- shell-script -*- +# Configurable variable values for Mailutils test suite. +# Copyright (C) 2004, 2010 Free Software Foundation, Inc. + +PATH=@abs_builddir@:@abs_top_builddir@/comsat:$top_srcdir:$srcdir:$PATH + diff --git a/comsat/tests/testsuite.at b/comsat/tests/testsuite.at new file mode 100644 index 000000000..6da4a4208 --- /dev/null +++ b/comsat/tests/testsuite.at @@ -0,0 +1,174 @@ +# This file is part of GNU Mailutils. -*- Autotest -*- +# Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. + +m4_include([testsuite.inc]) + +dnl ------------------------------------------------------------ +dnl mailbox for comsatd +m4_pushdef([BIFF_MBOX],[`pwd`/mailbox]) + +dnl ------------------------------------------------------------ +dnl comsatcmd +m4_pushdef([comsatcmd],[comsatd --no-site --no-user --file ./biff.rc dnl + --set logging.syslog=no --test]) + +dnl ------------------------------------------------------------ +dnl BIFFTEST(DESCR, KW, DATA, CMDLINE, [STDOUT = `'], [STDERR = `']) +dnl +m4_pushdef([BIFFTEST],[ +AT_SETUP([comsatd: $1]) +AT_KEYWORDS([comsatd $2]) +$3 +AT_CHECK([$4],[0],[$5],[$6]) +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 +EOT +chmod 600 biff.rc +> $cwd/output +], +[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 +--- +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 +EOT +chmod 600 biff.rc +> $cwd/output +], +[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) +--- +What a funny watch! It tells the day of the +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 +EOT +chmod 600 biff.rc +> $cwd/output +], +[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> +Subject: Re: Story +--- +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 +EOT +chmod 600 biff.rc +> $cwd/output +], +[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> +Subject: Request for a story (was Re: A guess) +--- +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 +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 +cat output +], +[You have mail from March Hare <hare@wonder.land>, regarding Invitation +]) + +m4_popdef([BIFFTEST]) +m4_popdef([comsatcmd]) +m4_popdef([BIFF_MBOX]) diff --git a/configure.ac b/configure.ac index aafad7f31..447701f5f 100644 --- a/configure.ac +++ b/configure.ac @@ -1212,6 +1212,7 @@ AC_CONFIG_TESTDIR(messages/tests) AC_CONFIG_TESTDIR(readmsg/tests) AC_CONFIG_TESTDIR(sieve/tests) AC_CONFIG_TESTDIR(mh/tests) +AC_CONFIG_TESTDIR(comsat/tests) AC_CONFIG_FILES([libmailutils/tests/Makefile libmailutils/tests/atlocal @@ -1219,6 +1220,8 @@ AC_CONFIG_FILES([libmailutils/tests/Makefile libmu_compat/tests/atlocal testsuite/Makefile testsuite/atlocal + comsat/tests/Makefile + comsat/tests/atlocal frm/tests/Makefile frm/tests/atlocal maidag/tests/Makefile |