curl/lib/getpass.c

222 lines
4.9 KiB
C
Raw Normal View History

1999-12-29 22:20:26 +08:00
/* ============================================================================
* Copyright (C) 1998 Angus Mackay. All rights reserved;
*
* Redistribution and use are freely permitted provided that:
*
* 1) This header remain in tact.
* 2) The prototypes for getpass and getpass_r are not changed from:
* char *getpass(const char *prompt)
* char *getpass_r(const char *prompt, char* buffer, int buflen)
1999-12-29 22:20:26 +08:00
* 3) This source code is not used outside of this(getpass.c) file.
* 4) Any changes to this(getpass.c) source code are made publicly available.
1999-12-29 22:20:26 +08:00
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* ============================================================================
*
* $Id$
*
* The spirit of this license is to allow use of this source code in any
* project be it open or closed but still encourage the use of the open,
* library based equivilents.
*
* Author(s):
* Angus Mackay <amackay@gus.ml.org>
*
* Contributor(s):
2000-06-20 23:31:26 +08:00
* Daniel Stenberg <daniel@haxx.se>
1999-12-29 22:20:26 +08:00
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifndef HAVE_GETPASS_R
#ifndef WIN32
1999-12-29 22:20:26 +08:00
#ifdef HAVE_TERMIOS_H
# if !defined(HAVE_TCGETATTR) && !defined(HAVE_TCSETATTR)
# undef HAVE_TERMIOS_H
# endif
#endif
#ifndef RETSIGTYPE
# define RETSIGTYPE void
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
#include <signal.h>
#ifdef HAVE_TERMIOS_H
# include <termios.h>
#else
# ifdef HAVE_TERMIO_H
# include <termio.h>
# else
# endif
#endif
2001-03-16 23:19:36 +08:00
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
1999-12-29 22:20:26 +08:00
/* no perror? make an fprintf! */
#ifndef HAVE_PERROR
# define perror(x) fprintf(stderr, "Error in: %s\n", x)
#endif
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
1999-12-29 22:20:26 +08:00
{
FILE *infp;
FILE *outfp;
RETSIGTYPE (*sigint)();
2000-03-20 03:54:13 +08:00
#ifndef __EMX__
1999-12-29 22:20:26 +08:00
RETSIGTYPE (*sigtstp)();
2000-03-20 03:54:13 +08:00
#endif
1999-12-29 22:20:26 +08:00
size_t bytes_read;
int infd;
int outfd;
#ifdef HAVE_TERMIOS_H
struct termios orig;
struct termios noecho;
#else
# ifdef HAVE_TERMIO_H
struct termio orig;
struct termio noecho;
# else
# endif
#endif
sigint = signal(SIGINT, SIG_IGN);
2000-03-20 03:54:13 +08:00
/* 20000318 mgs
* this is needed by the emx system, SIGTSTP is not a supported signal */
#ifndef __EMX__
1999-12-29 22:20:26 +08:00
sigtstp = signal(SIGTSTP, SIG_IGN);
2000-03-20 03:54:13 +08:00
#endif
1999-12-29 22:20:26 +08:00
if( (infp=fopen("/dev/tty", "r")) == NULL )
{
infp = stdin;
}
if( (outfp=fopen("/dev/tty", "w")) == NULL )
{
outfp = stderr;
}
infd = fileno(infp);
outfd = fileno(outfp);
/* dissable echo */
#ifdef HAVE_TERMIOS_H
if(tcgetattr(outfd, &orig) != 0)
{
; /*perror("tcgetattr");*/
1999-12-29 22:20:26 +08:00
}
noecho = orig;
noecho.c_lflag &= ~ECHO;
if(tcsetattr(outfd, TCSANOW, &noecho) != 0)
{
; /*perror("tcgetattr");*/
1999-12-29 22:20:26 +08:00
}
#else
# ifdef HAVE_TERMIO_H
if(ioctl(outfd, TCGETA, &orig) != 0)
{
; /*perror("ioctl");*/
1999-12-29 22:20:26 +08:00
}
noecho = orig;
noecho.c_lflag &= ~ECHO;
if(ioctl(outfd, TCSETA, &noecho) != 0)
{
; /*perror("ioctl");*/
1999-12-29 22:20:26 +08:00
}
# else
# endif
#endif
fputs(prompt, outfp);
fflush(outfp);
bytes_read=read(infd, buffer, buflen);
buffer[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
1999-12-29 22:20:26 +08:00
/* print a new line if needed */
#ifdef HAVE_TERMIOS_H
fputs("\n", outfp);
#else
# ifdef HAVE_TERMIO_H
fputs("\n", outfp);
# else
# endif
#endif
/*
* reset term charectaristics, use TCSAFLUSH incase the
* user types more than buflen
1999-12-29 22:20:26 +08:00
*/
#ifdef HAVE_TERMIOS_H
if(tcsetattr(outfd, TCSAFLUSH, &orig) != 0)
{
; /*perror("tcgetattr");*/
1999-12-29 22:20:26 +08:00
}
#else
# ifdef HAVE_TERMIO_H
if(ioctl(outfd, TCSETA, &orig) != 0)
{
; /*perror("ioctl");*/
1999-12-29 22:20:26 +08:00
}
# else
# endif
#endif
signal(SIGINT, sigint);
2000-03-23 18:41:39 +08:00
#ifndef __EMX__
1999-12-29 22:20:26 +08:00
signal(SIGTSTP, sigtstp);
2000-03-23 18:41:39 +08:00
#endif
1999-12-29 22:20:26 +08:00
return buffer; /* we always return success */
1999-12-29 22:20:26 +08:00
}
#else /* WIN32 */
1999-12-29 22:20:26 +08:00
#include <stdio.h>
#include <conio.h>
char *getpass_r(const char *prompt, char *buffer, int buflen)
1999-12-29 22:20:26 +08:00
{
int i;
printf("%s", prompt);
for(i=0; i<buflen; i++) {
buffer[i] = getch();
if ( buffer[i] == '\r' ) {
buffer[i] = 0;
break;
}
}
/* if user didn't hit ENTER, terminate buffer */
if (i==buflen)
buffer[buflen-1]=0;
return buffer; /* we always return success */
1999-12-29 22:20:26 +08:00
}
#endif
#endif /* ifndef HAVE_GETPASS_R */
#if 0
/* for consistensy, here's the old-style function: */
char *getpass(const char *prompt)
{
static char buf[256];
return getpass_r(prompt, buf, sizeof(buf));
}
#endif