summaryrefslogtreecommitdiffabout
path: root/comsat/action.c
Side-by-side diff
Diffstat (limited to 'comsat/action.c') (more/less context) (ignore whitespace changes)
-rw-r--r--comsat/action.c156
1 files changed, 83 insertions, 73 deletions
diff --git a/comsat/action.c b/comsat/action.c
index c9703f2..b6799c4 100644
--- a/comsat/action.c
+++ b/comsat/action.c
@@ -173,98 +173,114 @@ expand_line (const char *str, mu_message_t msg)
}
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"),
device, mu_strerror (status));
return NULL;
}
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;
}
mu_stream_t
open_tty (const char *device, int argc, char **argv)
@@ -272,27 +288,21 @@ 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));
+ {
+ 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
{
mu_stream_t tty;
mu_stream_t logstr;
mu_message_t msg;
@@ -608,13 +618,13 @@ void
run_user_action (const char *device, mu_message_t msg)
{
int rc, mode;
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;
env.errbuf = NULL;
env.errsize = 0;

Return to:

Send suggestions and report system problems to the System administrator.