summaryrefslogtreecommitdiffabout
path: root/libmailutils
authorSergey Poznyakoff <gray@gnu.org.ua>2010-10-05 18:53:39 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2010-10-05 18:53:39 (GMT)
commit8575afa0eb3a3f38642e28ec5ab109bc128c62dd (patch) (side-by-side diff)
tree29539bcff711fbc5b4142422404aea282c82a7d9 /libmailutils
parent63d1c19652942be6b600a5855880667f16fdb8a3 (diff)
downloadmailutils-8575afa0eb3a3f38642e28ec5ab109bc128c62dd.tar.gz
mailutils-8575afa0eb3a3f38642e28ec5ab109bc128c62dd.tar.bz2
Implement echo control on fd streams. Implement mu_getpass function.
* configure.ac: Test for tcgetattr and tcsetattr. * gnulib.modules (getpass-gnu): Remove. * include/mailutils/mutil.h (mu_getpass): New proto. * include/mailutils/stream.h (MU_IOCTL_GET_ECHO) (MU_IOCTL_SET_ECHO): New ioctls. * include/mailutils/sys/file_stream.h (_MU_FILE_STREAM_ECHO_OFF): New flag. (_mu_file_stream) <echo_state>: New member. * libmailutils/getpass.c: New file. * libmailutils/Makefile.am (libmailutils_la_SOURCES): Add getpass.c. * libmailutils/file_stream.c (fd_done): Free echo_state. (fd_ioctl): Implement MU_IOCTL_GET_ECHO and MU_IOCTL_SET_ECHO. * mu/mu.h (mustrin): New extern. * mu/pop.c (com_pass): Use mu_getpass. * mu/shell.c (mustrin): New variable. (readline): Use mu_stream_getline instead of getline. (mutool_shell): Create mustrin. * pop3d/popauth.c (options): Fix typo. (fill_pass): Use mu_getpass.
Diffstat (limited to 'libmailutils') (more/less context) (ignore whitespace changes)
-rw-r--r--libmailutils/Makefile.am1
-rw-r--r--libmailutils/file_stream.c94
-rw-r--r--libmailutils/getpass.c59
3 files changed, 146 insertions, 8 deletions
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am
index e05edd8..3f083e0 100644
--- a/libmailutils/Makefile.am
+++ b/libmailutils/Makefile.am
@@ -84,6 +84,7 @@ libmailutils_la_SOURCES = \
folder.c\
freeitem.c\
gdebug.c\
+ getpass.c\
gocs.c\
hdritr.c\
header.c\
diff --git a/libmailutils/file_stream.c b/libmailutils/file_stream.c
index 247768c..578f482 100644
--- a/libmailutils/file_stream.c
+++ b/libmailutils/file_stream.c
@@ -23,6 +23,9 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
#include <mailutils/types.h>
#include <mailutils/alloc.h>
@@ -183,6 +186,8 @@ fd_done (struct _mu_stream *str)
fd_close (str);
if (fstr->filename)
free (fstr->filename);
+ if (fstr->echo_state)
+ free (fstr->echo_state);
}
const char *
@@ -194,6 +199,10 @@ fd_error_string (struct _mu_stream *str, int rc)
return mu_strerror (rc);
}
+#ifndef TCSASOFT
+# define TCSASOFT 0
+#endif
+
static int
fd_ioctl (struct _mu_stream *str, int code, void *ptr)
{
@@ -218,17 +227,86 @@ fd_ioctl (struct _mu_stream *str, int code, void *ptr)
break;
case MU_IOCTL_GET_TRANSPORT_BUFFER:
- {
- struct mu_buffer_query *qp = ptr;
- return mu_stream_get_buffer (str, qp);
- }
+ if (!ptr)
+ return EINVAL;
+ else
+ {
+ struct mu_buffer_query *qp = ptr;
+ return mu_stream_get_buffer (str, qp);
+ }
case MU_IOCTL_SET_TRANSPORT_BUFFER:
- {
- struct mu_buffer_query *qp = ptr;
- return mu_stream_set_buffer (str, qp->buftype, qp->bufsize);
- }
+ if (!ptr)
+ return EINVAL;
+ else
+ {
+ struct mu_buffer_query *qp = ptr;
+ return mu_stream_set_buffer (str, qp->buftype, qp->bufsize);
+ }
+
+ case MU_IOCTL_SET_ECHO:
+ if (!ptr)
+ return EINVAL;
+ else
+ {
+ int status;
+ struct termios t;
+ int state = *(int*)ptr;
+#if HAVE_TCGETATTR
+ if (state == 0)
+ {
+ if (fstr->flags & _MU_FILE_STREAM_ECHO_OFF)
+ return 0;
+ status = tcgetattr (fstr->fd, &t);
+ if (status == 0)
+ {
+ fstr->echo_state = malloc (sizeof (t));
+ if (!fstr->echo_state)
+ return ENOMEM;
+ memcpy (fstr->echo_state, &t, sizeof (t));
+
+ t.c_lflag &= ~(ECHO | ISIG);
+ status = tcsetattr (fstr->fd, TCSAFLUSH | TCSASOFT, &t);
+ if (status == 0)
+ fstr->flags |= _MU_FILE_STREAM_ECHO_OFF;
+ }
+ if (status)
+ {
+ status = errno;
+ if (fstr->echo_state)
+ {
+ free (fstr->echo_state);
+ fstr->echo_state = NULL;
+ }
+ }
+ }
+ else
+ {
+ if (!(fstr->flags & _MU_FILE_STREAM_ECHO_OFF))
+ return 0;
+ if (tcsetattr (fstr->fd, TCSAFLUSH | TCSASOFT, fstr->echo_state))
+ status = errno;
+ else
+ {
+ status = 0;
+ free (fstr->echo_state);
+ fstr->echo_state = NULL;
+ fstr->flags &= ~_MU_FILE_STREAM_ECHO_OFF;
+ }
+ }
+ return status;
+#else
+ return ENOSYS;
+#endif
+ }
+ case MU_IOCTL_GET_ECHO:
+ if (!ptr)
+ return EINVAL;
+ else
+ *(int*)ptr = fstr->flags & _MU_FILE_STREAM_ECHO_OFF;
+ break;
+
default:
return ENOSYS;
}
diff --git a/libmailutils/getpass.c b/libmailutils/getpass.c
new file mode 100644
index 0000000..8a37c52
--- a/dev/null
+++ b/libmailutils/getpass.c
@@ -0,0 +1,59 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 1999, 2000, 2001, 2002, 2004,
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This library 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <mailutils/types.h>
+#include <mailutils/stream.h>
+#include <mailutils/mutil.h>
+#include <mailutils/cstr.h>
+
+int
+mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt,
+ char **passptr)
+{
+ int status;
+ int echo_state = 0;
+ size_t size = 0;
+ char *buf = NULL;
+
+ status = mu_stream_write (out, prompt, strlen (prompt), NULL);
+ if (status)
+ return status;
+ mu_stream_flush (out);
+ status = mu_stream_ioctl (in, MU_IOCTL_SET_ECHO, &echo_state);
+ if (status == 0)
+ echo_state = 1;
+ status = mu_stream_getline (in, &buf, &size, NULL);
+ if (echo_state)
+ {
+ mu_stream_ioctl (in, MU_IOCTL_SET_ECHO, &echo_state);
+ mu_stream_write (out, "\n", 1, NULL);
+ }
+ if (status == 0)
+ {
+ mu_rtrim_cset (buf, "\n");
+ *passptr = buf;
+ }
+ return 0;
+}
+

Return to:

Send suggestions and report system problems to the System administrator.