]> pd.if.org Git - zpackage/blob - lib/readpass.c
e48cbf33689890fdb0d42dade660ef46883dc2ad
[zpackage] / lib / readpass.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <termios.h>
8
9 char *readpass(char *prompt) {
10         FILE *term;
11         struct termios saved, noecho;
12         char *termpath, *pass = 0;;
13         int fd;
14         size_t len = 0;
15         ssize_t res;
16
17         termpath = ctermid(0);
18         if (!*termpath) {
19                 errno = ENOTTY;
20                 return 0;
21         }
22         term = fopen(termpath, "r+");
23         if (!term) {
24                 return 0;
25         }
26
27         fd = fileno(term);
28
29         if (tcgetattr(fd, &saved) != 0) {
30                 return 0;
31         }
32         noecho = saved;
33         noecho.c_lflag &= ~ECHO;
34
35         if (tcsetattr(fd, TCSAFLUSH, &noecho) != 0) {
36                 return 0;
37         }
38
39         if (prompt) {
40                 fprintf(term, "%s", prompt);
41                 fflush(term);
42         }
43
44         /* Read the password. */
45         res = getline(&pass, &len, term);
46         fprintf(term, "\n");
47         fflush(term);
48         fclose(term);
49
50         if (res == -1) {
51                 free(pass);
52                 return 0;
53         }
54
55         if (res == 0) {
56                 /* should be impossible */
57                 free(pass);
58                 return 0;
59         }
60
61         pass[res-1] = 0;
62
63         /* Restore terminal. */
64         tcsetattr(fd, TCSAFLUSH, &saved);
65
66         return pass;
67 }