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) (unidiff)
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 @@
1GNU mailutils NEWS -- history of user-visible changes. 2019-08-29 1GNU mailutils NEWS -- history of user-visible changes. 2019-09-03
2Copyright (C) 2002-2019 Free Software Foundation, Inc. 2Copyright (C) 2002-2019 Free Software Foundation, Inc.
3See the end of file for copying conditions. 3See the end of file for copying conditions.
4 4
@@ -23,6 +23,11 @@ Example configuration (pop3s server):
23 ssl-certificate-file /etc/ssl/cert.pem; 23 ssl-certificate-file /etc/ssl/cert.pem;
24 } 24 }
25 25
26* comsatd --test
27
28The --test option takes optional argument: name of the tty or file to
29use for reporting.
30
26 31
27Version 3.7 - 2019-06-21 32Version 3.7 - 2019-06-21
28 33
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 =
176#include "biff.rc.h" 176#include "biff.rc.h"
177; 177;
178 178
179/* Examine the tty to determine which filters to apply when printing
180 to it. On entry, STR is the opened stream, FLT points to an array
181 of char* with at least 3 slots, and NFLT to an integer number.
182 On success, populates FLT with the necessary filter chain, and stores
183 to *NFLT the number of used slots. On error, issues error message and
184 returns -1.
185 FLT and NFLT can be used as input to mu_filter_chain_create.
186 */
179static int 187static int
180need_crlf (mu_stream_t str) 188study_tty (mu_stream_t str, char *flt[], int *nflt)
181{ 189{
182#if defined(OPOST) && defined(ONLCR)
183 mu_transport_t trans[2]; 190 mu_transport_t trans[2];
184 struct termios tbuf; 191 int fd;
192 struct stat st;
193 int rc;
185 194
186 if (mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans)) 195 rc = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans);
187 return 1; /* suppose we do need it */ 196 if (rc)
188 if (tcgetattr ((int) (intptr_t) trans[0], &tbuf) == 0 && 197 {
189 (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)) 198 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_ioctl", NULL, rc);
190 return 0; 199 return rc;
191 else 200 }
192 return 1; 201
202 *nflt = 0;
203 fd = (int) (intptr_t) trans[0];
204 if (fstat (fd, &st) == 0)
205 {
206 switch (st.st_mode & S_IFMT)
207 {
208 case S_IFREG:
209 return 0;
210
211 case S_IFCHR:
212 flt[(*nflt)++] = "7BIT";
213#if defined(OPOST) && defined(ONLCR)
214 {
215 struct termios tbuf;
216
217 if (!(tcgetattr (fd, &tbuf) == 0
218 && (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)))
219 {
220 flt[(*nflt)++] = "+";
221 flt[(*nflt)++] = "CRLF";
222 }
223 }
193#else 224#else
194 return 1; /* Just in case */ 225 /* Just in case */
226 flt[(*nflt)++] = "+";
227 flt[(*nflt)++] = "CRLF";
195#endif 228#endif
229 break;
230
231 case S_IFSOCK:
232 return 0;
233
234 default:
235 /* FIXME: Perhaps an error? */
236 return 0;
237 }
238 }
239
240 return 0;
196} 241}
197 242
198static mu_stream_t 243static mu_stream_t
199_open_tty (const char *device, int argc, char **argv) 244_open_tty (const char *device, int argc, char **argv)
200{ 245{
201 mu_stream_t dev, base_dev, prev_stream; 246 mu_stream_t dev;
202 int status; 247 int status;
248 char *dfl_argv[4];
203 249
204 status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE); 250 status = mu_file_stream_create (&dev, device, MU_STREAM_APPEND|MU_STREAM_CREAT);
205 if (status) 251 if (status)
206 { 252 {
207 mu_error (_("cannot open device %s: %s"), 253 mu_error (_("cannot open device %s: %s"),
@@ -210,58 +256,28 @@ _open_tty (const char *device, int argc, char **argv)
210 } 256 }
211 mu_stream_set_buffer (dev, mu_buffer_line, 0); 257 mu_stream_set_buffer (dev, mu_buffer_line, 0);
212 258
213 prev_stream = base_dev = dev; 259 if (argc == 0)
214 while (argc)
215 { 260 {
216 int i; 261 status = study_tty (dev, dfl_argv, &argc);
217 int mode; 262 if (status)
218 int qmark; 263 return NULL;
219 char *fltname; 264 argv = dfl_argv;
220 265 }
221 fltname = argv[0]; 266
222 if (fltname[0] == '?') 267 if (argc)
223 { 268 {
224 qmark = 1; 269 mu_stream_t str;
225 fltname++; 270 status = mu_filter_chain_create (&str, dev,
226 } 271 MU_FILTER_ENCODE, MU_STREAM_WRITE,
227 else 272 argc, argv);
228 qmark = 0; 273 mu_stream_unref (dev);
229 274 if (status)
230 if (fltname[0] == '~')
231 {
232 mode = MU_FILTER_DECODE;
233 fltname++;
234 }
235 else
236 {
237 mode = MU_FILTER_ENCODE;
238 }
239
240 for (i = 1; i < argc; i++)
241 if (strcmp (argv[i], "+") == 0)
242 break;
243
244 if (qmark == 0 || need_crlf (base_dev))
245 {
246 status = mu_filter_create_args (&dev, prev_stream, fltname,
247 i, (const char **)argv,
248 mode, MU_STREAM_WRITE);
249 mu_stream_unref (prev_stream);
250 if (status)
251 {
252 mu_error (_("cannot open filter stream: %s"),
253 mu_strerror (status));
254 return NULL;
255 }
256 prev_stream = dev;
257 }
258 argc -= i;
259 argv += i;
260 if (argc)
261 { 275 {
262 argc--; 276 mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_chain_create", device,
263 argv++; 277 status);
278 return NULL;
264 } 279 }
280 dev = str;
265 } 281 }
266 return dev; 282 return dev;
267} 283}
@@ -275,21 +291,15 @@ open_tty (const char *device, int argc, char **argv)
275 { 291 {
276 int rc = mu_nullstream_create (&dev, MU_STREAM_WRITE); 292 int rc = mu_nullstream_create (&dev, MU_STREAM_WRITE);
277 if (rc) 293 if (rc)
278 mu_error (_("cannot open null stream: %s"), mu_strerror (rc)); 294 {
295 mu_error (_("cannot open null stream: %s"), mu_strerror (rc));
296 dev = NULL;
297 }
279 } 298 }
280 else 299 else
281 dev = _open_tty (device, argc, argv); 300 dev = _open_tty (device, argc, argv);
282 return dev; 301 return dev;
283} 302}
284
285static mu_stream_t
286open_default_tty (const char *device)
287{
288 static char *default_filters[] = { "7bit", "+", "?CRLF", NULL };
289 return open_tty (device, MU_ARRAY_SIZE (default_filters) - 1,
290 default_filters);
291}
292
293 303
294struct biffrc_environ 304struct biffrc_environ
295{ 305{
@@ -611,7 +621,7 @@ run_user_action (const char *device, mu_message_t msg)
611 mu_stream_t stream; 621 mu_stream_t stream;
612 struct biffrc_environ env; 622 struct biffrc_environ env;
613 623
614 env.tty = open_default_tty (device); 624 env.tty = open_tty (device, 0, NULL);
615 if (!env.tty) 625 if (!env.tty)
616 return; 626 return;
617 env.msg = msg; 627 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 @@
18#include "mailutils/syslog.h" 18#include "mailutils/syslog.h"
19#include "mailutils/cli.h" 19#include "mailutils/cli.h"
20#include "mailutils/sockaddr.h" 20#include "mailutils/sockaddr.h"
21#include "mailutils/alloc.h"
21 22
22#ifndef PATH_DEV 23#ifndef PATH_DEV
23# define PATH_DEV "/dev" 24# define PATH_DEV "/dev"
@@ -59,7 +60,7 @@ typedef struct utmp UTMP;
59 60
60const char *program_version = "comsatd (" PACKAGE_STRING ")"; 61const char *program_version = "comsatd (" PACKAGE_STRING ")";
61 62
62int test_mode; 63char *test_mode;
63char *biffrc = BIFF_RC; 64char *biffrc = BIFF_RC;
64mu_m_server_t server; 65mu_m_server_t server;
65 66
@@ -69,7 +70,26 @@ set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt,
69{ 70{
70 mu_m_server_set_mode (server, MODE_INTERACTIVE); 71 mu_m_server_set_mode (server, MODE_INTERACTIVE);
71} 72}
72 73
74static void
75set_test_mode (struct mu_parseopt *po, struct mu_option *opt,
76 char const *arg)
77{
78 if (arg)
79 {
80 if (arg[0] != '/')
81 {
82 test_mode = mu_make_file_name (mu_getcwd (), arg);
83 if (!test_mode)
84 mu_alloc_die ();
85 }
86 else
87 test_mode = mu_strdup (arg);
88 }
89 else
90 test_mode = mu_strdup ("/dev/tty");
91}
92
73static void 93static void
74set_daemon_mode (struct mu_parseopt *po, struct mu_option *opt, 94set_daemon_mode (struct mu_parseopt *po, struct mu_option *opt,
75 char const *arg) 95 char const *arg)
@@ -97,9 +117,9 @@ set_foreground (struct mu_parseopt *po, struct mu_option *opt,
97} 117}
98 118
99static struct mu_option comsat_options[] = { 119static struct mu_option comsat_options[] = {
100 { "test", 't', NULL, MU_OPTION_DEFAULT, 120 { "test", 't', N_("FILE"), MU_OPTION_ARG_OPTIONAL,
101 N_("run in test mode"), 121 N_("run in test mode; use FILE as tty (default: /dev/tty)"),
102 mu_c_bool, &test_mode }, 122 mu_c_string, &test_mode, set_test_mode },
103 { "foreground", 0, NULL, MU_OPTION_DEFAULT, 123 { "foreground", 0, NULL, MU_OPTION_DEFAULT,
104 N_("remain in foreground"), 124 N_("remain in foreground"),
105 mu_c_bool, NULL, set_foreground }, 125 mu_c_bool, NULL, set_foreground },
@@ -605,7 +625,7 @@ main (int argc, char **argv)
605 free (cwd); 625 free (cwd);
606 } 626 }
607 627
608 notify_user (user, "/dev/tty", argv[0], argv[1]); 628 notify_user (user, test_mode, argv[0], argv[1]);
609 exit (0); 629 exit (0);
610 } 630 }
611 631
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])
23dnl ------------------------------------------------------------ 23dnl ------------------------------------------------------------
24dnl comsatcmd 24dnl comsatcmd
25m4_pushdef([comsatcmd],[comsatd --no-site-config --file ./biff.rc dnl 25m4_pushdef([comsatcmd],[comsatd --no-site-config --file ./biff.rc dnl
26 --set logging.syslog=no --test]) 26 --set logging.syslog=no --test=output])
27 27
28dnl ------------------------------------------------------------ 28dnl ------------------------------------------------------------
29dnl BIFFTEST(DESCR, KW, DATA, CMDLINE, [STDOUT = `'], [STDERR = `']) 29dnl BIFFTEST(DESCR, KW, DATA, CMDLINE, [STDOUT = `'], [STDERR = `'])
@@ -34,8 +34,10 @@ dnl
34m4_pushdef([BIFFTEST],[ 34m4_pushdef([BIFFTEST],[
35AT_SETUP([comsatd: $1]) 35AT_SETUP([comsatd: $1])
36AT_KEYWORDS([comsatd $2]) 36AT_KEYWORDS([comsatd $2])
37AT_CHECK([test -w / && AT_SKIP_TEST
38cwd=`pwd`
37$3 39$3
38AT_CHECK([test -w / && AT_SKIP_TEST; $4],[0],[$5],[$6]) 40],[0],[$4],[$5])
39AT_CLEANUP]) 41AT_CLEANUP])
40 42
41AT_INIT 43AT_INIT
@@ -45,16 +47,9 @@ AT_TESTED([comsatd])
45MUT_VERSION(comsatd) 47MUT_VERSION(comsatd)
46 48
47BIFFTEST([default commands],[comsatd00], 49BIFFTEST([default commands],[comsatd00],
48[cwd=`pwd` 50[
49MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox) 51MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox)
50cat > biff.rc <<EOT 52comsatcmd $cwd/mailbox 0
51tty $cwd/output
52default
53EOT
54chmod 600 biff.rc
55> $cwd/output
56],
57[comsatcmd $cwd/mailbox 0
58sed '1s/^Mail to .*/Mail to test user/' output 53sed '1s/^Mail to .*/Mail to test user/' output
59], 54],
60[Mail to test user 55[Mail to test user
@@ -69,16 +64,9 @@ Have some wine
69]) 64])
70 65
71BIFFTEST([non-zero qid],[comsatd01], 66BIFFTEST([non-zero qid],[comsatd01],
72[cwd=`pwd` 67[
73MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox) 68MUT_MBCOPY($abs_top_srcdir/testsuite/spool/teaparty.mbox, mailbox)
74cat > biff.rc <<EOT 69comsatcmd $cwd/mailbox 9367
75tty $cwd/output
76default
77EOT
78chmod 600 biff.rc
79> $cwd/output
80],
81[comsatcmd $cwd/mailbox 9367
82sed '1s/^Mail to .*/Mail to test user/' output 70sed '1s/^Mail to .*/Mail to test user/' output
83], 71],
84[Mail to test user 72[Mail to test user
@@ -94,16 +82,9 @@ month, and doesn't tell what o'clock it is!
94]) 82])
95 83
96BIFFTEST([maildir qid],[comsatd02], 84BIFFTEST([maildir qid],[comsatd02],
97[cwd=`pwd` 85[
98MUT_MBCOPY($abs_top_srcdir/testsuite/maildir/teaparty, mailbox) 86MUT_MBCOPY($abs_top_srcdir/testsuite/maildir/teaparty, mailbox)
99cat > biff.rc <<EOT 87test "$MAILDIR_SUPPORT" = yes || AT_SKIP_TEST
100tty $cwd/output
101default
102EOT
103chmod 600 biff.rc
104> $cwd/output
105],
106[test "$MAILDIR_SUPPORT" = yes || AT_SKIP_TEST
107comsatcmd maildir:$cwd/mailbox new/1284627340.M364969P3770Q81.Trurl 88comsatcmd maildir:$cwd/mailbox new/1284627340.M364969P3770Q81.Trurl
108sed '1s/^Mail to .*/Mail to test user/' output 89sed '1s/^Mail to .*/Mail to test user/' output
109], 90],
@@ -119,16 +100,9 @@ What did they draw?
119 100
120 101
121BIFFTEST([MH qid],[comsatd03], 102BIFFTEST([MH qid],[comsatd03],
122[cwd=`pwd` 103[
123MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty, mailbox) 104MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty, mailbox)
124cat > biff.rc <<EOT 105test "$MH_SUPPORT" = yes || AT_SKIP_TEST
125tty $cwd/output
126default
127EOT
128chmod 600 biff.rc
129> $cwd/output
130],
131[test "$MH_SUPPORT" = yes || AT_SKIP_TEST
132comsatcmd mh:$cwd/mailbox teaparty/58 106comsatcmd mh:$cwd/mailbox teaparty/58
133sed '1s/^Mail to .*/Mail to test user/' output 107sed '1s/^Mail to .*/Mail to test user/' output
134], 108],
@@ -144,16 +118,13 @@ I vote the young lady tells us a story.
144]) 118])
145 119
146BIFFTEST([beep command],[comsatd04], 120BIFFTEST([beep command],[comsatd04],
147[cwd=`pwd` 121[
148MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox1, mailbox) 122MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox1, mailbox)
149cat > biff.rc <<EOT 123cat > biff.rc <<EOT
150tty $cwd/output
151beep 124beep
152EOT 125EOT
153chmod 600 biff.rc 126chmod 600 biff.rc
154> $cwd/output 127comsatcmd $cwd/mailbox 0
155],
156[comsatcmd $cwd/mailbox 0
157cat output | tr '\a' A 128cat output | tr '\a' A
158], 129],
159[AA]) 130[AA])
@@ -166,13 +137,10 @@ echo "You have mail from $1, regarding $2"
166]) 137])
167chmod +x notifier 138chmod +x notifier
168cat > biff.rc <<EOT 139cat > biff.rc <<EOT
169tty $cwd/output
170exec $cwd/notifier '\$H{from}' '\$H{Subject}' 140exec $cwd/notifier '\$H{from}' '\$H{Subject}'
171EOT 141EOT
172chmod 600 biff.rc 142chmod 600 biff.rc
173> $cwd/output 143comsatcmd $cwd/mailbox 0
174],
175[comsatcmd $cwd/mailbox 0
176cat output 144cat output
177], 145],
178[You have mail from March Hare <hare@wonder.land>, regarding Invitation 146[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 @@
5@pindex comsatd 5@pindex comsatd
6 6
7Comsatd is the server which receives reports of incoming mail and 7Comsatd is the server which receives reports of incoming mail and
8notifies users, wishing to get this service. It can be started 8notifies users about it. By default, it prints subject, sender
9either from @file{inetd.conf} or as a standalone daemon. 9name and email, followed by first five lines of each newly arrived message
10to the tty of the recipient user. Users can customize this behavior.
10 11
11@menu 12@menu
12* Starting comsatd:: Invocation. 13* Starting comsatd:: Invocation.
@@ -33,16 +34,33 @@ comsatd -c /etc/comsat.conf
33 34
34This is the default operation mode. 35This is the default operation mode.
35 36
36@item -t 37@item -t[@var{file}]
37@itemx --test 38@itemx --test[=@var{file}]
38Test mode. In this mode, @command{comsatd} takes two arguments: 39Test mode. In this mode, @command{comsatd} takes two arguments:
39@acronym{URL} of a mailbox and @acronym{QID} of the message from that 40@acronym{URL} of a mailbox and @acronym{QID} of the message from that
40mailbox, e.g.: 41mailbox and prints the notification to the current user tty
42(@file{/dev/tty}), or @var{file}, if it is supplied. If the
43@file{~/.biffrc} file exists, it will be used. For example:
41 44
42@example 45@example
43$ comsatd --test /var/mail/root 34589 46$ comsatd --test /var/mail/root 34589
44@end example 47@end example
45 48
49Notice, that @var{file} is an optional argument. When supplied, it
50should follow the short option form immediately, or the long option
51form after the equals sign, e.g.:
52
53@example
54$ comsatd --test=logfile /var/mail/root 34589
55@end example
56
57@noindent
58or
59
60@example
61$ comsatd -tlogfile /var/mail/root 34589
62@end example
63
46@item --foreground 64@item --foreground
47Don't detach from the controlling terminal, remain in foreground. 65Don't detach from the controlling terminal, remain in foreground.
48@end table 66@end table

Return to:

Send suggestions and report system problems to the System administrator.