/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
13 by Björn Påhlsson
Added following support:
1
#define _GNU_SOURCE		/* getline() */
2
#define _FORTIFY_SOURCE 2
3
#include <termios.h> 		/* struct termios, tcsetattr(),
4
				   TCSAFLUSH, tcgetattr(), ECHO */
5
#include <unistd.h>		/* struct termios, tcsetattr(),
6
				   STDIN_FILENO, TCSAFLUSH,
7
				   tcgetattr(), ECHO */
8
#include <signal.h>		/* sig_atomic_t, raise(), struct
9
				   sigaction, sigemptyset(),
10
				   sigaction(), sigaddset(), SIGINT,
11
				   SIGQUIT, SIGHUP, SIGTERM */
12
#include <stddef.h>		/* NULL, size_t */
13
#include <sys/types.h>		/* ssize_t */
14
#include <stdlib.h>		/* EXIT_SUCCESS, EXIT_FAILURE */
15
#include <stdio.h>		/* fprintf(), stderr, getline(),
16
				   stdin, feof(), perror(), fputc(),
17
				   stdout */
18
#include <errno.h>		/* errno, EINVAL */
19
#include <iso646.h>		/* or, not */
20
#include <stdbool.h>		/* bool, false, true */
21
22
volatile bool quit_now = false;
23
24
void termination_handler(int signum){
25
  quit_now = true;
26
}
27
28
int main(int argc, char **argv){
29
  ssize_t ret = -1;
30
  size_t n;
31
  struct termios t_new, t_old;
32
  char *buffer = NULL;
33
  int status = EXIT_SUCCESS;
34
  struct sigaction old_action,
35
    new_action = { .sa_handler = termination_handler,
36
		   .sa_flags = 0 };
37
  
38
  if (tcgetattr(STDIN_FILENO, &t_old) != 0){
39
    return EXIT_FAILURE;
40
  }
41
  
42
  sigemptyset(&new_action.sa_mask);
43
  sigaddset(&new_action.sa_mask, SIGINT);
44
  sigaddset(&new_action.sa_mask, SIGQUIT);
45
  sigaddset(&new_action.sa_mask, SIGHUP);
46
  sigaddset(&new_action.sa_mask, SIGTERM);
47
  sigaction(SIGINT, NULL, &old_action);
48
  if (old_action.sa_handler != SIG_IGN)
49
    sigaction(SIGINT, &new_action, NULL);
50
  sigaction(SIGQUIT, NULL, &old_action);
51
  if (old_action.sa_handler != SIG_IGN)
52
    sigaction(SIGQUIT, &new_action, NULL);
53
  sigaction(SIGHUP, NULL, &old_action);
54
  if (old_action.sa_handler != SIG_IGN)
55
    sigaction(SIGHUP, &new_action, NULL);
56
  sigaction(SIGTERM, NULL, &old_action);
57
  if (old_action.sa_handler != SIG_IGN)
58
    sigaction(SIGTERM, &new_action, NULL);
59
  
60
  t_new = t_old;
61
  t_new.c_lflag &= ~ECHO;
62
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
63
    perror("tcsetattr-echo");
64
    return EXIT_FAILURE;
65
  }
66
  
67
  while(true){
68
    if (quit_now){
69
      status = EXIT_FAILURE;
70
      break;
71
    }
72
    fprintf(stderr, "Password: ");
73
    ret = getline(&buffer, &n, stdin);
74
    if (ret > 0){
75
      fprintf(stdout, "%s", buffer);
76
      status = EXIT_SUCCESS;
77
      break;
78
    }
79
    // ret == 0 makes no other sence than to retry to read from stdin
80
    if (ret < 0){
81
      if (errno != EINTR and not feof(stdin)){
82
	perror("getline");
83
	status = EXIT_FAILURE;
84
	break;
85
      }
86
    }
87
    fputc('\n', stderr);
88
  }
89
90
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
91
    perror("tcsetattr+echo");
92
  }
93
  
94
  return status;
95
}