PageRenderTime 65ms CodeModel.GetById 48ms app.highlight 12ms RepoModel.GetById 2ms app.codeStats 0ms

/contrib/cvs/lib/getpass.c

https://bitbucket.org/freebsd/freebsd-head/
C | 111 lines | 66 code | 14 blank | 31 comment | 17 complexity | c2e8cafbabe31efba0838a4921374636 MD5 | raw file
  1/* Copyright (C) 1992,93,94,95,96,97,98,99,2000, 2001 Free Software Foundation, Inc.
  2   This file is part of the GNU C Library.
  3
  4   This program is free software; you can redistribute it and/or modify
  5   it under the terms of the GNU General Public License as published by
  6   the Free Software Foundation; either version 2, or (at your option)
  7   any later version.
  8
  9   This program is distributed in the hope that it will be useful,
 10   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12   GNU General Public License for more details.
 13
 14   You should have received a copy of the GNU General Public License along
 15   with this program; if not, write to the Free Software Foundation,
 16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 17
 18#if HAVE_CONFIG_H
 19# include <config.h>
 20#endif
 21
 22#include <stdio.h>
 23#ifndef SEEK_CUR
 24#define SEEK_CUR 1
 25#endif
 26#include <termios.h>
 27#include <unistd.h>
 28#include "getline.h"
 29
 30/* It is desirable to use this bit on systems that have it.
 31   The only bit of terminal state we want to twiddle is echoing, which is
 32   done in software; there is no need to change the state of the terminal
 33   hardware.  */
 34
 35#ifndef TCSASOFT
 36# define TCSASOFT 0
 37#endif
 38
 39char *
 40#if __STDC__
 41getpass (const char *prompt)
 42#else
 43getpass (prompt)
 44     const char *prompt;
 45#endif
 46{
 47  FILE *in, *out;
 48  struct termios s, t;
 49  int tty_changed;
 50  static char *buf;
 51  static size_t bufsize;
 52  ssize_t nread;
 53
 54  /* Try to write to and read from the terminal if we can.
 55     If we can't open the terminal, use stderr and stdin.  */
 56
 57  in = fopen ("/dev/tty", "w+");
 58  if (in == NULL)
 59    {
 60      in = stdin;
 61      out = stderr;
 62    }
 63  else
 64    out = in;
 65
 66  /* Turn echoing off if it is on now.  */
 67
 68  if (tcgetattr (fileno (in), &t) == 0)
 69    {
 70      /* Save the old one. */
 71      s = t;
 72      /* Tricky, tricky. */
 73      t.c_lflag &= ~(ECHO|ISIG);
 74      tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);
 75    }
 76  else
 77    tty_changed = 0;
 78
 79  /* Write the prompt.  */
 80  fputs (prompt, out);
 81  fflush (out);
 82
 83  /* Read the password.  */
 84  nread = getline (&buf, &bufsize, in);
 85  if (buf != NULL)
 86    {
 87      if (nread < 0)
 88	buf[0] = '\0';
 89      else if (buf[nread - 1] == '\n')
 90	{
 91	  /* Remove the newline.  */
 92	  buf[nread - 1] = '\0';
 93	  if (tty_changed)
 94	    {
 95	      /* Write the newline that was not echoed.  */
 96	      if (out == in) fseek (out, 0, SEEK_CUR);
 97	      putc ('\n', out);
 98	    }
 99	}
100    }
101
102  /* Restore the original setting.  */
103  if (tty_changed)
104    (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);
105
106  if (in != stdin)
107    /* We opened the terminal; now close it.  */
108    fclose (in);
109
110  return buf;
111}