1/* Copyright (C) 1992-1998 Free Software Foundation, Inc. 2This file is part of the GNU C Library. 3 4The GNU C Library is free software; you can redistribute it and/or 5modify it under the terms of the GNU Library General Public License as 6published by the Free Software Foundation; either version 2 of the 7License, or (at your option) any later version. 8 9The GNU C Library is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12Library General Public License for more details. 13 14You should have received a copy of the GNU Library General Public 15License along with the GNU C Library; see the file COPYING.LIB. If 16not, write to the Free Software Foundation, Inc., 675 Mass Ave, 17Cambridge, MA 02139, USA. */ 18 19/* Modified to use with samba by Jeremy Allison, 8th July 1995. */ 20 21#include "includes.h" 22 23#ifdef REPLACE_GETPASS 24 25#ifdef SYSV_TERMIO 26 27/* SYSTEM V TERMIO HANDLING */ 28 29static struct termio t; 30 31#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) 32#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) 33#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) 34 35#ifndef TCSAFLUSH 36#define TCSAFLUSH 1 37#endif 38 39#ifndef TCSANOW 40#define TCSANOW 0 41#endif 42 43static int tcgetattr(int fd, struct termio *t) 44{ 45 return ioctl(fd, TCGETA, t); 46} 47 48static int tcsetattr(int fd, int flags, struct termio *t) 49{ 50 if(flags & TCSAFLUSH) 51 ioctl(fd, TCFLSH, TCIOFLUSH); 52 return ioctl(fd, TCSETS, t); 53} 54 55#elif !defined(TCSAFLUSH) 56 57/* BSD TERMIO HANDLING */ 58 59static struct sgttyb t; 60 61#define ECHO_IS_ON(t) ((t).sg_flags & ECHO) 62#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO) 63#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO) 64 65#define TCSAFLUSH 1 66#define TCSANOW 0 67 68static int tcgetattr(int fd, struct sgttyb *t) 69{ 70 return ioctl(fd, TIOCGETP, (char *)t); 71} 72 73static int tcsetattr(int fd, int flags, struct sgttyb *t) 74{ 75 return ioctl(fd, TIOCSETP, (char *)t); 76} 77 78#else /* POSIX TERMIO HANDLING */ 79#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) 80#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) 81#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) 82 83static struct termios t; 84#endif /* SYSV_TERMIO */ 85 86static SIG_ATOMIC_T gotintr; 87static int in_fd = -1; 88 89/*************************************************************** 90 Signal function to tell us were ^C'ed. 91****************************************************************/ 92 93static void gotintr_sig(void) 94{ 95 gotintr = 1; 96 if (in_fd != -1) 97 close(in_fd); /* Safe way to force a return. */ 98 in_fd = -1; 99} 100 101char *getsmbpass(const char *prompt) 102{ 103 FILE *in, *out; 104 int echo_off; 105 static char buf[256]; 106 static size_t bufsize = sizeof(buf); 107 size_t nread; 108 109 /* Catch problematic signals */ 110 CatchSignal(SIGINT, SIGNAL_CAST gotintr_sig); 111 112 /* Try to write to and read from the terminal if we can. 113 If we can't open the terminal, use stderr and stdin. */ 114 115 in = fopen ("/dev/tty", "w+"); 116 if (in == NULL) { 117 in = stdin; 118 out = stderr; 119 } else { 120 out = in; 121 } 122 123 setvbuf(in, NULL, _IONBF, 0); 124 125 /* Turn echoing off if it is on now. */ 126 127 if (tcgetattr (fileno (in), &t) == 0) { 128 if (ECHO_IS_ON(t)) { 129 TURN_ECHO_OFF(t); 130 echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0; 131 TURN_ECHO_ON(t); 132 } else { 133 echo_off = 0; 134 } 135 } else { 136 echo_off = 0; 137 } 138 139 /* Write the prompt. */ 140 fputs(prompt, out); 141 fflush(out); 142 143 /* Read the password. */ 144 buf[0] = 0; 145 if (!gotintr) { 146 in_fd = fileno(in); 147 fgets(buf, bufsize, in); 148 } 149 nread = strlen(buf); 150 if (buf[nread - 1] == '\n') 151 buf[nread - 1] = '\0'; 152 153 /* Restore echoing. */ 154 if (echo_off) { 155 if (gotintr && in_fd == -1) 156 in = fopen ("/dev/tty", "w+"); 157 if (in != NULL) 158 tcsetattr (fileno (in), TCSANOW, &t); 159 } 160 161 fprintf(out, "\n"); 162 fflush(out); 163 164 if (in != stdin) /* We opened the terminal; now close it. */ 165 fclose(in); 166 167 /* Catch problematic signals */ 168 CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL); 169 170 if (gotintr) { 171 printf("Interupted by signal.\n"); 172 fflush(stdout); 173 exit(1); 174 } 175 return buf; 176} 177 178#else 179 void getsmbpasswd_dummy(void); 180 void getsmbpasswd_dummy(void) {;} 181#endif 182