My reimplementation and cleanup of the getpass source code. We officially no
authorDaniel Stenberg <daniel@haxx.se>
Sat, 25 Dec 2004 22:08:02 +0000 (22:08 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 25 Dec 2004 22:08:02 +0000 (22:08 +0000)
longer use Angus Mackay's getpass code due to the weirdo license his code was
donated to us under.

configure.ac
src/getpass.c
src/getpass.h
src/setup.h

index 8868cfe..406d27f 100644 (file)
@@ -1263,13 +1263,12 @@ AC_CHECK_FUNCS( strtoll \
                 inet_addr \
                 inet_ntoa \
                 inet_pton \
-                tcsetattr \
-                tcgetattr \
                 perror \
                 closesocket \
                 siginterrupt \
                 sigaction \
                 signal \
+                getpass \
                 getpass_r \
                 strlcat \
                 getpwuid \
index af377b1..6ef8d30 100644 (file)
@@ -1,47 +1,73 @@
-/* ============================================================================
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
  *
- * Redistribution and use are freely permitted provided that:
+ * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
- *   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)
- *   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.
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
  *
- * 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.
- * ============================================================================
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
  *
- * $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.
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
  *
- * Author(s):
- *   Angus Mackay <amackay@gus.ml.org>
- *   Daniel Stenberg <daniel@haxx.se>
- */
+ * $Id$
+ ***************************************************************************/
 
-#include "setup.h" /* setup.h is required for read() prototype */
+/* This file is a reimplementation of the previous one, due to license
+   problems. */
 
-#ifndef HAVE_GETPASS_R
+#include "setup.h"
 
-#include "getpass.h"
+#ifndef HAVE_GETPASS_R
+/* this file is only for systems without getpass_r() */
 
-#ifndef WIN32
-#ifdef  VMS
 #include <stdio.h>
 #include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "getpass.h"
+
+#ifdef HAVE_GETPASS
+char *getpass_r(const char *prompt, char *password, size_t passlen)
+{
+  char *ptr = getpass(prompt);
+  strncpy(password, ptr, passlen);
+  password[passlen-1]=0;
+  return password;
+}
+#define DONE
+#else
+/* the rest of this file is only for systems without getpass() */
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#else
+#ifdef HAVE_TERMIO_H
+#include <termio.h>
+#endif
+#endif
+
+/* The last #include file should be: */
+#if defined(CURLDEBUG) && defined(CURLTOOLDEBUG)
+#include "memdebug.h"
+#endif
+
+#ifdef VMS
+/* VMS implementation */
 #include descrip
 #include starlet
 #include iodef
@@ -78,139 +104,16 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
   }
   return buffer; /* we always return success */
 }
-#else /* VMS */
-#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
-
-/* The last #include file should be: */
-#if defined(CURLDEBUG) && defined(CURLTOOLDEBUG)
-#include "memdebug.h"
-#endif
-
-char *getpass_r(const char *prompt, char *buffer, size_t buflen)
-{
-  FILE *infp;
-  char infp_fclose = 0;
-  FILE *outfp;
-  RETSIGTYPE (*sigint)(int);
-#ifdef SIGTSTP
-  RETSIGTYPE (*sigtstp)(int);
-#endif
-  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);
-#ifdef SIGTSTP
-  sigtstp = signal(SIGTSTP, SIG_IGN);
-#endif
-
-  infp=fopen("/dev/tty", "r");
-  if( NULL == infp )
-    infp = stdin;
-  else
-    infp_fclose = 1;
-
-  outfp = stderr;
-
-  infd = fileno(infp);
-  outfd = fileno(outfp);
-
-  /* dissable echo */
-#ifdef HAVE_TERMIOS_H
-  tcgetattr(outfd, &orig);
-
-  noecho = orig;
-  noecho.c_lflag &= ~ECHO;
-  tcsetattr(outfd, TCSANOW, &noecho);
-#else
-#  ifdef HAVE_TERMIO_H
-  ioctl(outfd, TCGETA, &orig);
-  noecho = orig;
-  noecho.c_lflag &= ~ECHO;
-  ioctl(outfd, TCSETA, &noecho);
-#  else
-#  endif
-#endif
-
-  fputs(prompt, outfp);
-  fflush(outfp);
-
-  bytes_read=read(infd, buffer, buflen);
-  buffer[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
-
-  /* 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
-   */
-#ifdef HAVE_TERMIOS_H
-  tcsetattr(outfd, TCSAFLUSH, &orig);
-#else
-#  ifdef HAVE_TERMIO_H
-  ioctl(outfd, TCSETA, &orig);
-#  else
-#  endif
-#endif
-
-  signal(SIGINT, sigint);
-#ifdef SIGTSTP
-  signal(SIGTSTP, sigtstp);
-#endif
-
-  if(infp_fclose)
-    fclose(infp);
-
-  return buffer; /* we always return success */
-}
+#define DONE
 #endif /* VMS */
-#else /* WIN32 */
-#include <stdio.h>
+
+#ifdef WIN32
+/* Windows implementation */
 #include <conio.h>
 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
 {
   size_t i;
-  printf("%s", prompt);
+  fputs(prompt, stderr);
 
   for(i=0; i<buflen; i++) {
     buffer[i] = getch();
@@ -230,15 +133,98 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
 
   return buffer; /* we always return success */
 }
+#define DONE
+#endif /* WIN32 */
+
+#ifndef DONE /* not previously provided */
+
+#ifdef HAVE_TERMIOS_H
+#define struct_term struct termios
+#else
+#ifdef HAVE_TERMIO_H
+#define struct_term  struct termio
+#else
+#undef struct_term
+#endif
 #endif
 
-#endif /* ifndef HAVE_GETPASS_R */
+static bool ttyecho(bool enable, int fd)
+{
+#ifdef struct_term
+  static struct_term withecho;
+  static struct_term noecho;
+#endif
+  if(!enable) {
+  /* dissable echo by extracting the current 'withecho' mode and remove the
+     ECHO bit and set back the struct */
+#ifdef HAVE_TERMIOS_H
+    tcgetattr(fd, &withecho);
+    noecho = withecho;
+    noecho.c_lflag &= ~ECHO;
+    tcsetattr(fd, TCSANOW, &noecho);
+#else /* HAVE_TERMIOS_H */
+#ifdef HAVE_TERMIO_H
+    ioctl(fd, TCGETA, &withecho);
+    noecho = withecho;
+    noecho.c_lflag &= ~ECHO;
+    ioctl(fd, TCSETA, &noecho);
+#else /* HAVE_TERMIO_H */
+/* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
+    (void)fd; /* prevent compiler warning on unused variable */
+    return FALSE; /* not disabled */
+#endif
+#endif
+    return TRUE; /* disabled */
+  }
+  else {
+    /* re-enable echo, assumes we disabled it before (and set the structs we
+       now use to reset the terminal status) */
+#ifdef HAVE_TERMIOS_H
+    tcsetattr(fd, TCSAFLUSH, &withecho);
+#else /* HAVE_TERMIOS_H */
+#ifdef HAVE_TERMIO_H
+    ioctl(fd, TCSETA, &withecho);
+#else
+/* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H */
+    return FALSE; /* not enabled */
+#endif
+#endif
+    return TRUE; /* enabled */
+  }
+}
 
-#if 0
-/* for consistensy, here's the old-style function: */
-char *getpass(const char *prompt)
+char *getpass_r(const char *prompt, /* prompt to display */
+                char *password,     /* buffer to store password in */
+                size_t buflen)      /* size of buffer to store password in */
 {
-  static char buf[256];
-  return getpass_r(prompt, buf, sizeof(buf));
+  ssize_t nread;
+  bool disabled;
+  int fd=open("/dev/tty", O_RDONLY);
+  if(-1 == fd)
+    fd = 1; /* use stdin if the tty couldn't be used */
+
+  disabled = ttyecho(FALSE, fd); /* disable terminal echo */
+
+  fputs(prompt, stderr);
+  nread=read(fd, password, buflen);
+  if(nread > 0)
+    password[--nread]=0; /* zero terminate where enter is stored */
+  else
+    password[0]=0; /* got nothing */
+
+  if(disabled) {
+    /* if echo actually was disabled, add a newline */
+    fputs("\n", stderr);
+    ttyecho(TRUE, fd); /* enable echo */
+  }
+
+  if(1 != fd)
+    close(fd);
+
+  return password; /* return pointer to buffer */
 }
-#endif
+
+#endif /* DONE */
+
+#endif /* HAVE_GETPASS */
+#endif /* HAVE_GETPASS_R */
index d1a2638..ed31704 100644 (file)
@@ -1,10 +1,10 @@
 #ifndef __GETPASS_H
 #define __GETPASS_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -12,7 +12,7 @@
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
index 288a012..b9b2283 100644 (file)
@@ -49,7 +49,7 @@
 #endif
 #endif
 
-#ifdef CURLDEBUG
+#if defined(CURLDEBUG) && defined(CURLTOOLDEBUG)
 /* This is an ugly hack for CURLDEBUG conditions only. We need to include
    the file here, since it might set the _FILE_OFFSET_BITS define, which must
    be set BEFORE all normal system headers. */