aboutsummaryrefslogtreecommitdiffstats
path: root/getpass.c
diff options
context:
space:
mode:
Diffstat (limited to 'getpass.c')
-rw-r--r--getpass.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/getpass.c b/getpass.c
new file mode 100644
index 00000000..c5fe4829
--- /dev/null
+++ b/getpass.c
@@ -0,0 +1,223 @@
+/* Copyright 1993-95 by Carl Harris, Jr.
+ * All rights reserved
+ *
+ * Distribute freely, except: don't remove my name from the source or
+ * documentation (don't take credit for my work), mark your changes (don't
+ * get me blamed for your possible bugs), don't alter or remove this
+ * notice. May be sold if buildable source is provided to buyer. No
+ * warrantee of any kind, express or implied, is included with this
+ * software; use at your own risk, responsibility for damages (if any) to
+ * anyone resulting from the use of this software rests entirely with the
+ * user.
+ *
+ * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
+ * I'll try to keep a version up to date. I can be reached as follows:
+ * Carl Harris <ceharris@mal.com>
+ */
+
+
+/***********************************************************************
+ module: getpass.c
+ project: popclient
+ programmer: Carl Harris, ceharris@mal.com
+ description: getpass() replacement which allows for long passwords.
+
+ $Log: getpass.c,v $
+ Revision 1.1 1996/06/28 14:33:54 esr
+ Initial revision
+
+ Revision 1.4 1995/08/10 00:32:27 ceharris
+ Preparation for 3.0b3 beta release:
+ - added code for --kill/--keep, --limit, --protocol, --flush
+ options; --pop2 and --pop3 options now obsoleted by --protocol.
+ - added support for APOP authentication, including --with-APOP
+ argument for configure.
+ - provisional and broken support for RPOP
+ - added buffering to SockGets and SockRead functions.
+ - fixed problem of command-line options not being correctly
+ carried into the merged options record.
+
+ Revision 1.3 1995/08/08 01:01:19 ceharris
+ Added GNU-style long options processing.
+ Fixed password in 'ps' output problem.
+ Fixed various RCS tag blunders.
+ Integrated .poprc parser, lexer, etc into Makefile processing.
+
+ ***********************************************************************/
+
+#include <config.h>
+
+#if defined(STDC_HEADERS)
+#include <stdio.h>
+#endif
+
+#include <signal.h>
+
+#define INPUT_BUF_SIZE MAX_PASSWORD_LENGTH
+
+#if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
+# include <termios.h>
+#else
+#if defined(HAVE_TERMIO_H)
+# include <sys/ioctl.h>
+# include <termio.h>
+#else
+#if defined(HAVE_SGTTY_H)
+# include <sgtty.h>
+#endif
+#endif
+#endif
+
+static int ttyfd;
+
+#if defined(HAVE_TCSETATTR)
+ static struct termios termb;
+ static tcflag_t flags;
+#else
+#if defined(HAVE_TERMIO_H)
+ static struct termio termb;
+ static unsigned short flags;
+#else
+#if defined(HAVE_STTY)
+ static struct sgttyb ttyb;
+ static int flags;
+#endif
+#endif
+#endif
+
+void save_tty_state();
+void disable_tty_echo();
+void restore_tty_state();
+
+char *
+getpassword(prompt)
+char *prompt;
+{
+
+#if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
+
+#if defined(HAVE_GETPASS)
+ char *getpass();
+ return getpass(prompt);
+#else
+ fputs("ERROR: no support for getpassword() routine\n",stderr);
+ exit(1);
+#endif
+
+#endif /* !(defined(HAVE_TCSETATTR) || ... */
+
+ register char *p;
+ register c;
+ FILE *fi;
+ static char pbuf[INPUT_BUF_SIZE];
+ RETSIGTYPE (*sig)();
+ RETSIGTYPE sigint_handler();
+
+
+ /* get the file descriptor for the input device */
+ if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
+ fi = stdin;
+ else
+ setbuf(fi, (char *)NULL);
+
+ /* store descriptor for the tty */
+ ttyfd = fileno(fi);
+
+ /* preserve tty state before turning off echo */
+ save_tty_state();
+
+ /* now that we have the current tty state, we can catch SIGINT and
+ exit gracefully */
+ sig = signal(SIGINT, sigint_handler);
+
+ /* turn off echo on the tty */
+ disable_tty_echo();
+
+ /* display the prompt and get the input string */
+ fprintf(stderr, "%s", prompt); fflush(stderr);
+ for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
+ if (p < &pbuf[INPUT_BUF_SIZE - 1])
+ *p++ = c;
+ }
+ *p = '\0';
+
+ /* write a newline so cursor won't appear to hang */
+ fprintf(stderr, "\n"); fflush(stderr);
+
+ /* restore previous state of the tty */
+ restore_tty_state();
+
+ /* restore previous state of SIGINT */
+ signal(SIGINT, sig);
+
+ if (fi != stdin)
+ fclose(fi);
+
+ return(pbuf);
+
+}
+
+
+void
+save_tty_state ()
+{
+#if defined(HAVE_TCSETATTR)
+ tcgetattr(ttyfd, &termb);
+ flags = termb.c_lflag;
+#else
+#if defined(HAVE_TERMIO_H)
+ ioctl(ttyfd, TCGETA, (char *) &termb);
+ flags = termb.c_lflag;
+#else /* we HAVE_STTY */
+ gtty(ttyfd, &ttyb);
+ flags = ttyb.sg_flags;
+#endif
+#endif
+}
+
+
+void
+disable_tty_echo()
+{
+ /* turn off echo on the tty */
+#if defined(HAVE_TCSETATTR)
+ termb.c_lflag &= ~ECHO;
+ tcsetattr(ttyfd, TCSAFLUSH, &termb);
+#else
+#if defined(HAVE_TERMIO_H)
+ termb.c_lflag &= ~ECHO;
+ ioctl(ttyfd, TCSETA, (char *) &termb);
+#else /* we HAVE_STTY */
+ ttyb.sg_flags &= ~ECHO;
+ stty(ttyfd, &ttyb);
+#endif
+#endif
+}
+
+
+
+void
+restore_tty_state()
+{
+ /* restore previous tty echo state */
+#if defined(HAVE_TCSETATTR)
+ termb.c_lflag = flags;
+ tcsetattr(ttyfd, TCSAFLUSH, &termb);
+#else
+#if defined(HAVE_TERMIO_H)
+ termb.c_lflag = flags;
+ ioctl(ttyfd, TCSETA, (char *) &termb);
+#else /* we HAVE_STTY */
+ ttyb.sg_flags = flags;
+ stty(ttyfd, &ttyb);
+#endif
+#endif
+}
+
+
+RETSIGTYPE sigint_handler ()
+{
+ restore_tty_state();
+ fputs("\nCaught signal... bailing out.\n", stderr);
+ exit(1);
+}