Commit 9e253b39 9e253b395de6ea7839b7f2b04b1a28892af514e7 by Sergey Poznyakoff

comsat: improve biffrc evaluation.

* comsat/.gitignore: Add biff.rc.h
* comsat/Makefile.am (comsatd_SOURCES, BUILT_SOURCES): Add biff.rc.h
(EXTRA_DIST): Add biffrc.sed and biff.rc
* comsat/action.c (default_action): Include biff.rc.h.
(biffrc_environ): New struct.
(eval_biffrc): New function.
(run_user_action): Rewrite via eval_biffrc.  Default action is
evaluated if biff.rc cannot be opened, or it contains the "default"
keyword.
* comsat/tests/testsuite.at: Add "default" statement where necessary.
1 parent 835ee6b0
......@@ -4,3 +4,4 @@ comsatd
.deps
.libs
.gdbinit
biff.rc.h
......
......@@ -19,9 +19,16 @@ INCLUDES = @MU_APP_COMMON_INCLUDES@
SUBDIRS = . tests
sbin_PROGRAMS = comsatd
comsatd_SOURCES = action.c comsat.c comsat.h
comsatd_SOURCES = action.c comsat.c comsat.h biff.rc.h
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
BUILT_SOURCES=biff.rc.h
EXTRA_DIST=biffrc.sed biff.rc
biff.rc.h: $(top_srcdir)/comsat/biff.rc
$(AM_V_GEN)sed -f $(top_srcdir)/comsat/biffrc.sed \
$(top_srcdir)/comsat/biff.rc > biff.rc.h
comsatd_LDADD = \
${MU_APP_LIBRARIES}\
${MU_LIB_MBOX}\
......
......@@ -181,13 +181,8 @@ expand_line (const char *str, mu_message_t msg)
}
const char *default_action =
"Mail to \a$u@$h\a\n"
"---\n"
"From: $H{from}\n"
"Subject: $H{Subject}\n"
"---\n"
"$B(,5)\n"
"---\n";
#include "biff.rc.h"
;
static void
action_beep (mu_stream_t tty)
......@@ -439,53 +434,36 @@ open_default_tty (const char *device)
default_filters);
}
void
run_user_action (const char *device, mu_message_t msg)
struct biffrc_environ
{
mu_stream_t tty;
mu_message_t msg;
mu_stream_t input;
int nact = 0;
mu_stream_t tty = open_default_tty (device);
struct mu_locus locus;
int use_default;
};
if (!tty)
return;
input = open_rc (biffrc, tty);
if (input)
{
void
eval_biffrc (struct biffrc_environ *env)
{
char *stmt = NULL;
size_t size = 0;
size_t n;
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);
if (!rcname)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name", NULL, ENOMEM);
locus.mu_file = BIFF_RC;
}
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)
while (mu_stream_getline (env->input, &stmt, &size, &n) == 0 && n > 0)
{
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_LOCUS, &env->locus);
if (mu_wordsplit (stmt, &ws, wsflags) == 0 && ws.ws_wordc)
{
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus);
if (strcmp (ws.ws_wordv[0], "beep") == 0)
{
/* FIXME: excess arguments are ignored */
action_beep (tty);
nact++;
action_beep (env->tty);
}
else
{
......@@ -497,7 +475,7 @@ run_user_action (const char *device, mu_message_t msg)
for (i = 1; i < ws.ws_wordc; i++)
{
char *oldarg = ws.ws_wordv[i];
ws.ws_wordv[i] = expand_line (ws.ws_wordv[i], msg);
ws.ws_wordv[i] = expand_line (ws.ws_wordv[i], env->msg);
free (oldarg);
if (!ws.ws_wordv[i])
break;
......@@ -510,13 +488,14 @@ run_user_action (const char *device, mu_message_t msg)
ws.ws_wordv + 2);
if (!ntty)
{
mu_stream_printf (tty,
_(".biffrc:%d: cannot open tty\n"),
locus.mu_line);
mu_stream_printf (env->tty,
_("%s:%d: cannot open tty\n"),
env->locus.mu_file,
env->locus.mu_line);
break;
}
mu_stream_destroy (&tty);
tty = ntty;
mu_stream_destroy (&env->tty);
env->tty = ntty;
}
else if (strcmp (ws.ws_wordv[0], "echo") == 0)
{
......@@ -527,38 +506,114 @@ run_user_action (const char *device, mu_message_t msg)
argc--;
argv++;
}
action_echo (tty, n_option, argc, argv);
nact++;
action_echo (env->tty, n_option, argc, argv);
}
else if (strcmp (ws.ws_wordv[0], "exec") == 0)
{
action_exec (tty, ws.ws_wordc - 1, ws.ws_wordv + 1);
nact++;
action_exec (env->tty, ws.ws_wordc - 1, ws.ws_wordv + 1);
}
else if (strcmp (ws.ws_wordv[0], "default") == 0)
{
env->use_default = 1;
}
else
{
mu_stream_printf (tty,
_(".biffrc:%d: unknown keyword\n"),
locus.mu_line);
mu_stream_printf (env->tty,
_("%s:%d: unknown keyword\n"),
env->locus.mu_file,
env->locus.mu_line);
mu_diag_output (MU_DIAG_ERROR, _("unknown keyword %s"),
ws.ws_wordv[0]);
break;
}
}
}
else
{
const char *diag = mu_wordsplit_strerror (&ws);
mu_stream_printf (env->tty,
_("%s:%d: %s\n"),
env->locus.mu_file,
env->locus.mu_line,
diag);
mu_diag_output (MU_DIAG_ERROR, "%s", diag);
}
wsflags |= MU_WRDSF_REUSE;
/* FIXME: line number is incorrect if .biffrc contains
escaped newlines */
locus.mu_line++;
env->locus.mu_line++;
}
free (stmt);
mu_wordsplit_free (&ws);
mu_stream_destroy (&input);
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL);
}
void
run_user_action (const char *device, mu_message_t msg)
{
mu_stream_t stream;
struct biffrc_environ env;
env.tty = open_default_tty (device);
if (!env.tty)
return;
env.msg = msg;
env.input = open_rc (biffrc, env.tty);
if (env.input)
{
char *cwd = mu_getcwd ();
char *rcname;
rcname = mu_make_file_name (cwd, BIFF_RC);
free (cwd);
if (!rcname)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name", NULL, ENOMEM);
env.locus.mu_file = BIFF_RC;
}
else
env.locus.mu_file = rcname;
env.locus.mu_line = 1;
env.locus.mu_col = 0;
env.use_default = 0;
eval_biffrc (&env);
mu_stream_destroy (&env.input);
free (rcname);
}
else
env.use_default = 1;
if (env.use_default &&
mu_static_memory_stream_create (&stream, default_action,
strlen (default_action)) == 0)
{
int rc = mu_filter_create (&env.input, stream, "LINECON",
MU_FILTER_DECODE,
MU_STREAM_READ);
mu_stream_unref (stream);
if (rc)
{
mu_stream_printf (env.tty,
_("Cannot create filter for the default action: %s\n"),
mu_strerror (rc));
mu_diag_output (MU_DIAG_NOTICE,
_("cannot create default filter for %s: %s"),
username, mu_strerror (rc));
}
else
{
env.locus.mu_file = "<default>";
env.locus.mu_line = 1;
env.locus.mu_col = 0;
eval_biffrc (&env);
mu_stream_destroy (&env.input);
}
}
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL);
if (nact == 0)
echo_string (tty, expand_line (default_action, msg));
mu_stream_destroy (&tty);
mu_stream_destroy (&env.tty);
}
......
# The default biffrc file for GNU Mailutils comsatd utility.
# 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/>.
echo "Mail to \a$u@$h\a\n---\n\
From: $H{from}\n\
Subject: $H{Subject}\n\
---\n\
$B(,5)\n\
---"
# 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/>.
# Provide leading quote
1i\
"\\
# Provide trailing quote
$a\
"
# Remove empty lines and comments
/#/d
/^ *$/d
# Escape quotes and backslashes
s/["\]/\\&/g
# Add newline and continuation character at the end of each line
s/$/\\n\\/
# End
......@@ -46,6 +46,7 @@ BIFFTEST([default commands],[comsatd00],
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
......@@ -69,6 +70,7 @@ BIFFTEST([non-zero qid],[comsatd01],
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
......@@ -93,6 +95,7 @@ BIFFTEST([maildir qid],[comsatd02],
MUT_MBCOPY($abs_top_srcdir/testsuite/maildir/teaparty, mailbox)
cat > biff.rc <<EOT
tty $cwd/output
default
EOT
chmod 600 biff.rc
> $cwd/output
......@@ -116,6 +119,7 @@ BIFFTEST([MH qid],[comsatd03],
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty, mailbox)
cat > biff.rc <<EOT
tty $cwd/output
default
EOT
chmod 600 biff.rc
> $cwd/output
......