1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#include "libbb.h"
39
40#ifdef __linux__
41#include <sys/vt.h>
42
43static void release_vt(int signo UNUSED_PARAM)
44{
45
46
47 ioctl(STDIN_FILENO, VT_RELDISP, (unsigned long) !option_mask32);
48}
49
50static void acquire_vt(int signo UNUSED_PARAM)
51{
52
53 ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
54}
55#endif
56
57int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
58int vlock_main(int argc UNUSED_PARAM, char **argv)
59{
60#ifdef __linux__
61 struct vt_mode vtm;
62 struct vt_mode ovtm;
63#endif
64 struct termios term;
65 struct termios oterm;
66 struct passwd *pw;
67
68 pw = xgetpwuid(getuid());
69 getopt32(argv, "^" "a" "\0" "=0");
70
71
72 bb_signals(0
73 + (1 << SIGTSTP)
74 + (1 << SIGTTIN)
75 + (1 << SIGTTOU)
76 + (1 << SIGHUP )
77 + (1 << SIGCHLD)
78 + (1 << SIGQUIT)
79 + (1 << SIGINT )
80 , SIG_IGN);
81
82#ifdef __linux__
83
84
85 signal_SA_RESTART_empty_mask(SIGUSR1, release_vt);
86 signal_SA_RESTART_empty_mask(SIGUSR2, acquire_vt);
87
88 sig_unblock(SIGUSR1);
89 sig_unblock(SIGUSR2);
90#endif
91
92
93
94 xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO);
95 xdup2(STDIN_FILENO, STDOUT_FILENO);
96
97#ifdef __linux__
98 xioctl(STDIN_FILENO, VT_GETMODE, &vtm);
99 ovtm = vtm;
100
101 vtm.mode = VT_PROCESS;
102 vtm.relsig = SIGUSR1;
103 vtm.acqsig = SIGUSR2;
104 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
105#endif
106
107
108 tcgetattr(STDIN_FILENO, &oterm);
109 term = oterm;
110 term.c_iflag |= IGNBRK;
111 term.c_iflag &= ~BRKINT;
112 term.c_lflag &= ~(ISIG | ECHO | ECHOCTL);
113 tcsetattr_stdin_TCSANOW(&term);
114
115 while (1) {
116 printf("Virtual console%s locked by %s.\n",
117 "s" + !option_mask32,
118 pw->pw_name
119 );
120 if (ask_and_check_password(pw) > 0) {
121 break;
122 }
123 pause_after_failed_login();
124 puts("Incorrect password");
125 }
126
127#ifdef __linux__
128 ioctl(STDIN_FILENO, VT_SETMODE, &ovtm);
129#endif
130 tcsetattr_stdin_TCSANOW(&oterm);
131 fflush_stdout_and_exit(EXIT_SUCCESS);
132}
133