]> pd.if.org Git - zpackage/commitdiff
add function to read a password
authorNathan Wagner <nw@hydaspes.if.org>
Mon, 25 Mar 2019 13:41:39 +0000 (13:41 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Mon, 25 Mar 2019 13:41:39 +0000 (13:41 +0000)
lib/readpass.c [new file with mode: 0644]

diff --git a/lib/readpass.c b/lib/readpass.c
new file mode 100644 (file)
index 0000000..e48cbf3
--- /dev/null
@@ -0,0 +1,67 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <termios.h>
+
+char *readpass(char *prompt) {
+       FILE *term;
+       struct termios saved, noecho;
+       char *termpath, *pass = 0;;
+       int fd;
+       size_t len = 0;
+       ssize_t res;
+
+       termpath = ctermid(0);
+       if (!*termpath) {
+               errno = ENOTTY;
+               return 0;
+       }
+       term = fopen(termpath, "r+");
+       if (!term) {
+               return 0;
+       }
+
+       fd = fileno(term);
+
+       if (tcgetattr(fd, &saved) != 0) {
+               return 0;
+       }
+       noecho = saved;
+       noecho.c_lflag &= ~ECHO;
+
+       if (tcsetattr(fd, TCSAFLUSH, &noecho) != 0) {
+               return 0;
+       }
+
+       if (prompt) {
+               fprintf(term, "%s", prompt);
+               fflush(term);
+       }
+
+       /* Read the password. */
+       res = getline(&pass, &len, term);
+       fprintf(term, "\n");
+       fflush(term);
+       fclose(term);
+
+       if (res == -1) {
+               free(pass);
+               return 0;
+       }
+
+       if (res == 0) {
+               /* should be impossible */
+               free(pass);
+               return 0;
+       }
+
+       pass[res-1] = 0;
+
+       /* Restore terminal. */
+       tcsetattr(fd, TCSAFLUSH, &saved);
+
+       return pass;
+}