2 * Copyright (c) 2017, S. Gilles <sgilles@math.umd.edu>
4 * Permission to use, copy, modify, and/or distribute this software
5 * for any purpose with or without fee is hereby granted, provided
6 * that the above copyright notice and this permission notice appear
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
13 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
14 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
34 static void jack(int s
)
39 static int get_username(const char **out_username
)
41 struct passwd
*passwd
;
45 if (!(passwd
= getpwuid(getuid()))) {
46 PERROR_MESSAGE("getpwuid");
51 *out_username
= passwd
->pw_name
;
56 static void redraw_screen(int failed
)
59 struct timespec req
= { .tv_sec
= 0, .tv_nsec
= 500000000 };
62 ioctl(fileno(stdin
), TIOCGWINSZ
, &ws
);
66 printf("\033[48;2;%d;%d;%dm", 0xcc, 0x33, 0x33);
68 printf("\033[48;2;%d;%d;%dm", 0x88, 0x88, 0x88);
71 for (int row
= 0; row
<= ws
.ws_row
; ++row
) {
72 printf("\033[%d;0f", row
);
74 for (int j
= 0; j
< ws
.ws_col
; ++j
) {
81 printf("\033[%d;%df", ws
.ws_row
/ 2 - 1, 0);
83 req
.tv_nsec
= 500000000 / ws
.ws_col
;
84 midcol
= ws
.ws_col
/ 2;
86 for (int j
= 0; j
<= ws
.ws_col
/ 2 + 1; ++j
) {
90 if (midcol
- j
>= 0) {
91 printf("\033[%d;%df", ws
.ws_row
/ 2 - 1, midcol
- j
);
93 printf("\033[%d;%df", ws
.ws_row
/ 2, midcol
- j
);
95 printf("\033[%d;%df", ws
.ws_row
/ 2 + 1, midcol
- j
);
100 if (midcol
+ j
<= ws
.ws_col
) {
101 printf("\033[%d;%df", ws
.ws_row
/ 2 - 1, midcol
+ j
);
103 printf("\033[%d;%df", ws
.ws_row
/ 2, midcol
+ j
);
105 printf("\033[%d;%df", ws
.ws_row
/ 2 + 1, midcol
+ j
);
113 printf("\033[%d;%df", ws
.ws_row
/ 2, 5);
117 static void get_correct_password(const char *username
)
124 redraw_screen(failed_yet
);
129 execl("/bin/su", "su", "-", username
, "-c", "true",
134 if (waitpid(pid
, &status
, 0) < 0) {
135 /* Waitpid failed. Too bad, user */
139 if (WIFEXITED(status
) &&
140 WEXITSTATUS(status
) == 0) {
148 static int ignore_signals(void)
150 struct sigaction sa
= { .sa_handler
= jack
, .sa_flags
= SA_RESTART
};
152 sigfillset(&sa
.sa_mask
);
154 if (sigaction(SIGUSR1
, &sa
, 0) < 0) {
155 PERROR_MESSAGE("sigaction");
160 if (sigaction(SIGUSR2
, &sa
, 0) < 0) {
161 PERROR_MESSAGE("sigaction");
166 if (sigaction(SIGINT
, &sa
, 0) < 0) {
167 PERROR_MESSAGE("sigaction");
172 if (sigaction(SIGTSTP
, &sa
, 0) < 0) {
173 PERROR_MESSAGE("sigaction");
183 const char *username
= 0;
185 if (ignore_signals() < 0) {
193 if (get_username(&username
) < 0) {
197 get_correct_password(username
);