]> Pileus Git - ~andy/fetchmail/blob - getpass.c
Code cleanup before teaching it to autoconfigure.
[~andy/fetchmail] / getpass.c
1 /*
2  * For license terms, see the file COPYING in this directory.
3  */
4
5 /***********************************************************************
6   module:       getpass.c
7   project:      fetchmail
8   programmer:   Carl Harris, ceharris@mal.com
9   description:  getpass() replacement which allows for long passwords.
10                 This version hacked by Wilfred Teiken, allowing the
11                 password to be piped to fetchmail.
12
13  ***********************************************************************/
14
15 #include "config.h"
16
17 #include <stdio.h>
18 #include <signal.h>
19 #include <fcntl.h>
20 #if defined(HAVE_UNISTD_H)
21 #include <unistd.h>
22 #endif
23 #include "fetchmail.h"
24
25 #define INPUT_BUF_SIZE  PASSWORDLEN
26
27 #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
28 #  include <termios.h>
29 #else
30 #if defined(HAVE_TERMIO_H)
31 #  include <sys/ioctl.h>
32 #  include <termio.h>
33 #else
34 #if defined(HAVE_SGTTY_H)
35 #  include <sgtty.h>
36 #endif
37 #endif
38 #endif
39
40 static int ttyfd;
41
42 #if defined(HAVE_TCSETATTR)
43   static struct termios termb;
44   static tcflag_t flags;
45 #else
46 #if defined(HAVE_TERMIO_H)
47   static struct termio termb;
48   static unsigned short flags;
49 #else
50 #if defined(HAVE_STTY)
51   static struct sgttyb ttyb;
52   static int flags;
53 #endif
54 #endif
55 #endif
56
57 void save_tty_state();
58 void disable_tty_echo();
59 void restore_tty_state();
60
61 char *getpassword(prompt)
62 char *prompt;
63 {
64 #if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
65
66 #if defined(HAVE_GETPASS) 
67     char *getpass();
68     return getpass(prompt);
69 #else
70     fputs("ERROR: no support for getpassword() routine\n",stderr);
71     exit(1);
72 #endif
73
74 #endif /* !(defined(HAVE_TCSETATTR) || ... */
75
76     register char *p;
77     register c;
78     FILE *fi;
79     static char pbuf[INPUT_BUF_SIZE];
80     RETSIGTYPE (*sig)();
81     RETSIGTYPE sigint_handler();
82     int istty = (tcgetpgrp(0) != -1);
83
84     /* get the file descriptor for the input device */
85
86     if (istty)
87     {
88         if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
89             fi = stdin;
90         else
91             setbuf(fi, (char *)NULL);
92     }
93     else
94         fi = stdin;
95
96     /* store descriptor for the tty */
97     ttyfd = fileno(fi);
98
99     if (istty)
100     {
101         /* preserve tty state before turning off echo */
102         save_tty_state();
103
104         /* now that we have the current tty state, we can catch SIGINT and  
105            exit gracefully */
106         sig = signal(SIGINT, sigint_handler);
107
108         /* turn off echo on the tty */
109         disable_tty_echo();
110
111         /* display the prompt and get the input string */
112         fprintf(stderr, "%s", prompt);
113     }
114
115     for (p = pbuf; (c = getc(fi))!='\n' && c!=EOF;)
116     {
117         if (p < &pbuf[INPUT_BUF_SIZE - 1])
118             *p++ = c;
119     }
120     *p = '\0';
121
122     /* write a newline so cursor won't appear to hang */
123     if (fi != stdin)
124         fprintf(stderr, "\n");
125
126     if (istty)
127     {
128         /* restore previous state of the tty */
129         restore_tty_state();
130
131         /* restore previous state of SIGINT */
132         signal(SIGINT, sig);
133     }
134     if (fi != stdin)
135         fclose(fi);
136
137     return(pbuf);
138 }
139
140
141 void
142 save_tty_state ()
143 {
144 #if defined(HAVE_TCSETATTR)
145     tcgetattr(ttyfd, &termb);
146     flags = termb.c_lflag;
147 #else
148 #if defined(HAVE_TERMIO_H)
149     ioctl(ttyfd, TCGETA, (char *) &termb);
150     flags = termb.c_lflag;
151 #else  /* we HAVE_STTY */
152     gtty(ttyfd, &ttyb);
153     flags = ttyb.sg_flags;
154 #endif
155 #endif
156 }
157
158
159 void
160 disable_tty_echo() 
161 {
162     /* turn off echo on the tty */
163 #if defined(HAVE_TCSETATTR)
164     termb.c_lflag &= ~ECHO;
165     tcsetattr(ttyfd, TCSAFLUSH, &termb);
166 #else
167 #if defined(HAVE_TERMIO_H)
168     termb.c_lflag &= ~ECHO;
169     ioctl(ttyfd, TCSETA, (char *) &termb);
170 #else  /* we HAVE_STTY */
171     ttyb.sg_flags &= ~ECHO;
172     stty(ttyfd, &ttyb);
173 #endif
174 #endif
175 }
176
177
178
179 void
180 restore_tty_state()
181 {
182     /* restore previous tty echo state */
183 #if defined(HAVE_TCSETATTR)
184     termb.c_lflag = flags;
185     tcsetattr(ttyfd, TCSAFLUSH, &termb);
186 #else
187 #if defined(HAVE_TERMIO_H)
188     termb.c_lflag = flags;
189     ioctl(ttyfd, TCSETA, (char *) &termb);
190 #else  /* we HAVE_STTY */
191     ttyb.sg_flags = flags;
192     stty(ttyfd, &ttyb);
193 #endif
194 #endif
195 }
196
197
198 RETSIGTYPE sigint_handler()
199 {
200     restore_tty_state();
201     error(1, 0, "\nCaught signal... bailing out.");
202 }