/*
fortunelock - Copyright (c) 1999/2000 Rob Kaper <cap@capsi.cx>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <signal.h>
#include <curses.h>
#include <string.h>
/* VT handling disabled until behavior under X or telnet/ssh is defined.
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
*/
#include <sys/time.h>
#include <unistd.h>
#include "fortunelock.h"
char passwd[PASSWDMAX+1], passwd_str[PASSWDMAX+1];
int main(int argc, char *argv[])
{
int passwd_set=0;
/* VT handling.
int tty;
struct vt_mode vtm;
*/
struct timeval timeout;
fd_set keypress;
void handle_sig(int);
/* VT handling. * /
if ((tty = open ("/dev/tty0", O_RDWR)) == -1)
{
perror ("open");
exit (-1);
}
if (-1 == ioctl (tty, VT_GETMODE, &vtm))
{
perror ("ioctl");
exit (-1);
}
vtm.mode = VT_PROCESS;
vtm.relsig = SIGUSR1;
vtm.acqsig = SIGUSR1;
if (-1 == ioctl (tty, VT_SETMODE, &vtm))
{
perror ("ioctl");
exit (-1);
}
*/
/* Default ncurses initialization. */
initscr(); cbreak(); noecho();
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
/* Print some nice stuff. */
print_header();
/*
print_fortune();
*/
refresh();
/* Fuck passwd, NIS, pam, shadow... user can set his/her own password. */
while(!passwd_set)
passwd_set=set_passwd();
/* Ctrl-C, Ctrl-Z and Ctrl-\ must be ignored (or actually handled). */
signal(SIGINT,handle_sig);
signal(SIGTSTP,handle_sig);
signal(SIGQUIT,handle_sig);
/* Key events need to be handled. */
signal(SIGUSR1,handle_sig);
/* Terminal is truly locked now. */
print_msg("Terminal locked.");
refresh();
/* The main loop. */
while(1)
{
timeout.tv_sec = 3;
timeout.tv_usec = 0;
FD_ZERO(&keypress);
FD_SET(0, &keypress);
select (1, &keypress, NULL, NULL, &timeout);
if (FD_ISSET(0, &keypress))
{
/* Let the user unlock by entering his/her password. */
strncpy(passwd_str, get_passwd(), PASSWDMAX);
passwd_str[PASSWDMAX]='\0';
/* Check the password, this will either exit itself or continue. */
check_passwd();
refresh();
}
else
{
print_fortune();
move(4, strlen("Enter the lock password to unlock: "));
refresh();
}
}
}
void handle_sig(int sig)
{
print_msg("Sorry, this terminal is locked.");
refresh();
/* Reset the signal handler. */
signal(sig,handle_sig);
}
void check_passwd(void)
{
/* Compare passwords. */
if (!strcmp(passwd, passwd_str))
{
/* Match. */
erase();
mvprintw(0, 0, "%-80s", "Terminal unlocked.");
refresh();
/* Exit. */
endwin();
exit(0);
}
else
print_msg("Password incorrect.");
}
int set_passwd(void)
{
/* Clear password strings. */
passwd[0]='\0';
passwd_str[0]='\0';
/* Enter once. */
while(!passwd[0])
{
mvprintw(3, 0, "Enter password to lock this terminal with: ");
refresh();
strncpy(passwd, get_passwd(), PASSWDMAX);
passwd[PASSWDMAX]='\0';
}
/* Enter twice. */
while(!passwd_str[0])
{
/*
print_fortune();
*/
mvprintw(4, 0, "Re-enter password to verify: ");
refresh();
strncpy(passwd_str, get_passwd(), PASSWDMAX);
passwd_str[PASSWDMAX]='\0';
}
/* Compare. */
if(strcmp(passwd, passwd_str))
{
/* No match. */
mvprintw(5, 0, "Passwords didn't match, try again please.");
refresh();
/* Return 0 to passwd_set. */
return 0;
}
else return 1;
}
char *get_passwd(void)
{
static char input[PASSWDMAX+1];
char tmp[PASSWDMAX+1];
int i=0, len=0;
/* Clear buffers. */
input[0]='\0';
tmp[0]='\0';
/* Keep reading those keystrokes. */
while(1)
{
/* Get keystroke. */
i=getch();
if (i==13)
/* Enter was pressed. */
return input;
/* Backspace was pressed, shorten the input buffer. */
else if (i==263)
{
len=strlen(input);
if (len>0)
input[len-1]='\0';
}
/* Enter the typed key into the buffer. */
else if (i>0)
{
strncpy(tmp, input, PASSWDMAX);
input[PASSWDMAX]='\0';
snprintf(input, PASSWDMAX, "%s%c", tmp, i);
input[PASSWDMAX]='\0';
}
refresh();
}
}
void print_msg(char *msg)
{
print_fortune();
mvprintw(3, 0, "%-80s", msg);
mvprintw(4, 0, "%-80s", "Enter the lock password to unlock: ");
move(4, strlen("Enter the lock password to unlock: "));
passwd_str[0]='\0';
}
void print_header(void)
{
mvprintw(0, 0, "------------------------------------------------------------------------------");
mvprintw(1, 0, "%-80s", "fortunelock " VERSION " - Copyright (c) 1999/2000 Rob Kaper <cap@capsi.cx>");
mvprintw(2, 0, "------------------------------------------------------------------------------");
}
void print_fortune(void)
{
FILE *f;
char str[80];
int line=5;
mvprintw(line++, 0, "------------------------------------------------------------------------------");
f=popen("fortune -s", "r");
if (f)
{
fgets(str, sizeof(str), f);
while(!feof(f))
{
mvprintw(line++, 0, "%-80s", str);
fgets(str, sizeof(str), f);
}
fclose(f);
}
else
mvprintw(line++, 0, "Fortune? Never heard of it.");
mvprintw(line++, 0, "------------------------------------------------------------------------------");
while(line<LINES)
mvprintw(line++, 0, " ");
}
syntax highlighted by Code2HTML, v. 0.9.1