diff options
Diffstat (limited to 'libmailutils')
-rw-r--r-- | libmailutils/Makefile.am | 1 | ||||
-rw-r--r-- | libmailutils/file_stream.c | 94 | ||||
-rw-r--r-- | libmailutils/getpass.c | 59 |
3 files changed, 146 insertions, 8 deletions
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index e05edd883..3f083e01d 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 247768c25..578f4829e 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 000000000..8a37c52cc --- /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; +} + |