diff options
Diffstat (limited to 'comsat/action.c')
-rw-r--r-- | comsat/action.c | 156 |
1 files changed, 83 insertions, 73 deletions
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; |