summaryrefslogtreecommitdiff
path: root/comsat
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-12-07 13:45:34 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2010-12-07 13:45:34 +0200
commitac08a8575ae8ea3b85180bd05464a48768f398ee (patch)
tree2b62fe9bd48cef51152a7c85f84123e3b6d590c5 /comsat
parentc2b4805128f2619235396726a116331606729e62 (diff)
downloadmailutils-ac08a8575ae8ea3b85180bd05464a48768f398ee.tar.gz
mailutils-ac08a8575ae8ea3b85180bd05464a48768f398ee.tar.bz2
comsat: Use mu streams instead of stdio
* comsat/action.c (action_beep, echo_string) (action_echo, action_exec): Take mu_stream_t as first argument. (open_rc): Take mu_stream_t as tty, return mu_stream_t as well. Install the linecon filter. (run_user_action): Take mu_stream_t as first arg. Pass it to all invoked actions. * comsat/comsat.c (get_newline_str): Remove. (need_crlf): New function. (notify_user): Use mu_stream_t instead of FILE. Install a 7bit filter and CRLF filter (if the device requires it). * comsat/comsat.h: Include mailutils/filter.h. (run_user_action): Change signature.
Diffstat (limited to 'comsat')
-rw-r--r--comsat/action.c118
-rw-r--r--comsat/comsat.c60
-rw-r--r--comsat/comsat.h3
3 files changed, 103 insertions, 78 deletions
diff --git a/comsat/action.c b/comsat/action.c
index 483b0571d..97f961c7f 100644
--- a/comsat/action.c
+++ b/comsat/action.c
@@ -17,7 +17,7 @@
#include "comsat.h"
#include <mailutils/io.h>
-#include <mailutils/filter.h>
+#include <mailutils/argcv.h>
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
#include <obstack.h>
@@ -188,65 +188,46 @@ const char *default_action =
"$B(,5)\n"
"---\n";
-/* Take care to clear eighth bit, so we won't upset some stupid terminals */
-#define LB(c) ((c)&0x7f)
-
static void
-action_beep (FILE *tty)
+action_beep (mu_stream_t tty)
{
- fprintf (tty, "\a\a");
+ mu_stream_write (tty, "\a\a", 2, NULL);
+ mu_stream_flush (tty);
}
static void
-echo_string (FILE *tty, const char *cr, char *str)
+echo_string (mu_stream_t tty, char *str)
{
if (!str)
return;
- for (; *str; str++)
- {
- if (*str == '\n')
- fprintf (tty, "%s", cr);
- else
- {
- char c = LB (*str);
- putc (c, tty);
- }
- }
- fflush (tty);
+ mu_stream_write (tty, str, strlen (str), NULL);
}
static void
-action_echo (FILE *tty, const char *cr, int omit_newline,
- int argc, char **argv)
+action_echo (mu_stream_t tty, int omit_newline, int argc, char **argv)
{
int i;
- if (omit_newline)
- {
- argc--;
- argv++;
- }
-
for (i = 0;;)
{
- echo_string (tty, cr, argv[i]);
+ echo_string (tty, argv[i]);
if (++i < argc)
- echo_string (tty, cr, " ");
+ echo_string (tty, " ");
else
- {
- if (!omit_newline)
- echo_string (tty, cr, "\n");
- break;
- }
+ break;
}
+ if (!omit_newline)
+ echo_string (tty, "\n");
}
static void
-action_exec (FILE *tty, int argc, char **argv)
+action_exec (mu_stream_t tty, int argc, char **argv)
{
- pid_t pid;
+ mu_stream_t pstream;
struct stat stb;
-
+ char *command;
+ int status;
+
if (argc == 0)
{
mu_diag_output (MU_DIAG_ERROR, _("no arguments for exec"));
@@ -272,22 +253,30 @@ action_exec (FILE *tty, int argc, char **argv)
return;
}
- pid = fork ();
- if (pid == 0)
+ /* FIXME: Redirect stderr to out */
+ /* FIXME: need this:
+ status = mu_prog_stream_create_argv (&pstream, argv[0], argv,
+ MU_STREAM_READ);
+ */
+ status = mu_argcv_join (argc, argv, " ", mu_argcv_escape_no, &command);
+ if (status)
{
- close (1);
- close (2);
- dup2 (fileno (tty), 1);
- dup2 (fileno (tty), 2);
- fclose (tty);
- execv (argv[0], argv);
- mu_diag_output (MU_DIAG_ERROR, _("cannot execute %s: %s"), argv[0], strerror (errno));
- exit (0);
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_argcv_join", NULL, status);
+ return;
+ }
+ status = mu_prog_stream_create (&pstream, command, MU_STREAM_READ);
+ if (status)
+ {
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_prog_stream_create_argv", argv[0],
+ status);
+ return;
}
+ mu_stream_copy (tty, pstream, 0, NULL);
+ mu_stream_destroy (&pstream);
}
static mu_stream_t
-open_rc (const char *filename, FILE *tty)
+open_rc (const char *filename, mu_stream_t tty)
{
struct stat stb;
struct passwd *pw = getpwnam (username);
@@ -307,8 +296,8 @@ open_rc (const char *filename, FILE *tty)
}
if ((stb.st_mode & 0777) != 0600)
{
- fprintf (tty, "%s\r\n",
- _("Warning: your .biffrc has wrong permissions"));
+ mu_stream_printf (tty, "%s\n",
+ _("Warning: your .biffrc has wrong permissions"));
mu_diag_output (MU_DIAG_NOTICE, _("%s's %s has wrong permissions"),
username, filename);
return NULL;
@@ -319,8 +308,8 @@ open_rc (const char *filename, FILE *tty)
{
if (rc != ENOENT)
{
- fprintf (tty, _("Cannot open .biffrc file: %s\r\n"),
- mu_strerror (rc));
+ mu_stream_printf (tty, _("Cannot open .biffrc file: %s\n"),
+ mu_strerror (rc));
mu_diag_output (MU_DIAG_NOTICE, _("cannot open %s for %s: %s"),
filename, username, mu_strerror (rc));
}
@@ -331,8 +320,9 @@ open_rc (const char *filename, FILE *tty)
mu_stream_unref (input);
if (rc)
{
- fprintf (tty, _("Cannot create filter for your .biffrc file: %s\r\n"),
- mu_strerror (rc));
+ mu_stream_printf (tty,
+ _("Cannot create filter for your .biffrc file: %s\n"),
+ mu_strerror (rc));
mu_diag_output (MU_DIAG_NOTICE,
_("cannot create filter for file %s of %s: %s"),
filename, username, mu_strerror (rc));
@@ -342,7 +332,7 @@ open_rc (const char *filename, FILE *tty)
}
void
-run_user_action (FILE *tty, const char *cr, mu_message_t msg)
+run_user_action (mu_stream_t tty, mu_message_t msg)
{
mu_stream_t input;
int nact = 0;
@@ -403,8 +393,14 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg)
if (strcmp (ws.ws_wordv[0], "echo") == 0)
{
- action_echo (tty, cr, n_option,
- ws.ws_wordc - 1, ws.ws_wordv + 1);
+ int argc = ws.ws_wordc - 1;
+ char **argv = ws.ws_wordv + 1;
+ if (n_option)
+ {
+ argc--;
+ argv++;
+ }
+ action_echo (tty, n_option, argc, argv);
nact++;
}
else if (strcmp (ws.ws_wordv[0], "exec") == 0)
@@ -414,9 +410,9 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg)
}
else
{
- fprintf (tty, _(".biffrc:%d: unknown keyword"),
- locus.mu_line);
- fprintf (tty, "\r\n");
+ mu_stream_printf (tty,
+ _(".biffrc:%d: unknown keyword\n"),
+ locus.mu_line);
mu_diag_output (MU_DIAG_ERROR, _("unknown keyword %s"),
ws.ws_wordv[0]);
break;
@@ -424,6 +420,8 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg)
}
}
mu_wordsplit_free (&ws);
+ /* FIXME: line number is incorrect if .biffrc contains
+ escaped newlines */
locus.mu_line++;
}
mu_stream_destroy (&input);
@@ -433,5 +431,5 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg)
}
if (nact == 0)
- echo_string (tty, cr, expand_line (default_action, msg));
+ echo_string (tty, expand_line (default_action, msg));
}
diff --git a/comsat/comsat.c b/comsat/comsat.c
index 8a22a3f45..faf18bef6 100644
--- a/comsat/comsat.c
+++ b/comsat/comsat.c
@@ -358,19 +358,22 @@ comsat_connection (int fd, struct sockaddr *sa, int salen,
return 0;
}
-static const char *
-get_newline_str (FILE *fp)
+static int
+need_crlf (mu_stream_t str)
{
#if defined(OPOST) && defined(ONLCR)
+ mu_transport_t trans[2];
struct termios tbuf;
- tcgetattr (fileno (fp), &tbuf);
- if ((tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR))
- return "\n";
+ 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 "\r\n";
+ return 1;
#else
- return "\r\n"; /* Just in case */
+ return 1; /* Just in case */
#endif
}
@@ -380,21 +383,43 @@ static void
notify_user (const char *user, const char *device, const char *path,
mu_message_qid_t qid)
{
- FILE *fp;
- const char *cr;
+ mu_stream_t out, dev;
mu_mailbox_t mbox = NULL;
mu_message_t msg;
int status;
if (change_user (user))
return;
- if ((fp = fopen (device, "w")) == NULL)
+ status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE);
+ if (status)
{
- mu_error (_("cannot open device %s: %s"), device, mu_strerror (errno));
+ mu_error (_("cannot open device %s: %s"), device, mu_strerror (status));
return;
}
-
- cr = get_newline_str (fp);
+ mu_stream_set_buffer (dev, mu_buffer_line, 0);
+
+ status = mu_filter_create (&out, dev, "7bit", MU_FILTER_ENCODE,
+ MU_STREAM_WRITE);
+ mu_stream_unref (dev);
+ if (status)
+ {
+ mu_error (_("cannot create 7bit filter: %s"), mu_strerror (status));
+ return;
+ }
+
+ if (need_crlf (out))
+ {
+ mu_stream_t str;
+ status = mu_filter_create (&str, out, "CRLF", MU_FILTER_ENCODE,
+ MU_STREAM_WRITE);
+ mu_stream_unref (out);
+ if (status)
+ {
+ mu_error (_("cannot create crlf filter: %s"), mu_strerror (status));
+ return;
+ }
+ out = str;
+ }
if (!path)
{
@@ -403,8 +428,9 @@ notify_user (const char *user, const char *device, const char *path,
return;
}
- if ((status = mu_mailbox_create (&mbox, path)) != 0
- || (status = mu_mailbox_open (mbox, MU_STREAM_READ|MU_STREAM_QACCESS)) != 0)
+ if ((status = mu_mailbox_create (&mbox, path)) != 0 ||
+ (status = mu_mailbox_open (mbox,
+ MU_STREAM_READ|MU_STREAM_QACCESS)) != 0)
{
mu_error (_("cannot open mailbox %s: %s"),
path, mu_strerror (status));
@@ -419,8 +445,8 @@ notify_user (const char *user, const char *device, const char *path,
return; /* FIXME: Notify the user, anyway */
}
- run_user_action (fp, cr, msg);
- fclose (fp);
+ run_user_action (out, msg);
+ mu_stream_destroy (&out);
}
/* Search utmp for the local user */
diff --git a/comsat/comsat.h b/comsat/comsat.h
index 85c09fd0e..e23aaba33 100644
--- a/comsat/comsat.h
+++ b/comsat/comsat.h
@@ -60,6 +60,7 @@
#include <mailutils/acl.h>
#include <mailutils/server.h>
#include <mailutils/cctype.h>
+#include <mailutils/filter.h>
#ifndef INADDR_NONE
# define INADDR_NONE -1
@@ -77,5 +78,5 @@ extern const char *username;
extern char *hostname;
extern struct daemon_param daemon_param;
-void run_user_action (FILE *tty, const char *cr, mu_message_t msg);
+void run_user_action (mu_stream_t str, mu_message_t msg);

Return to:

Send suggestions and report system problems to the System administrator.