mirror of https://github.com/fairyglade/ly.git
214 lines
4.5 KiB
C
214 lines
4.5 KiB
C
#define _XOPEN_SOURCE
|
|
|
|
/* stdlib */
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
/* linux */
|
|
#include <sys/wait.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/vt.h>
|
|
#include <unistd.h>
|
|
/* ncurses */
|
|
#include <form.h>
|
|
/* pam */
|
|
#include <security/pam_appl.h>
|
|
/* ly */
|
|
#include "lang.h"
|
|
#include "config.h"
|
|
#include "utils.h"
|
|
#include "login.h"
|
|
#include "desktop.h"
|
|
#include "ncui.h"
|
|
|
|
#define KEY_ENTER_ASCII 10
|
|
#define KEY_BACKSPACE_ASCII 127
|
|
|
|
int main(void)
|
|
{
|
|
FILE* console;
|
|
/* user interface components */
|
|
struct ncform form;
|
|
struct ncwin win;
|
|
/* desktop environments list */
|
|
enum deserv_t type;
|
|
struct delist_t* de_list;
|
|
struct deprops_t* de_props;
|
|
char** de_names;
|
|
int de_count;
|
|
int de_id;
|
|
/* user input */
|
|
int input_key;
|
|
/* processing buffers */
|
|
int fail;
|
|
int auth_fails;
|
|
char* username;
|
|
char* password;
|
|
char* cmd;
|
|
/* prevents CTRL+C from killing the process */
|
|
signal(SIGINT, SIG_IGN);
|
|
signal(SIGHUP, SIG_IGN);
|
|
/* gets desktop entries */
|
|
de_list = list_de();
|
|
de_props = de_list->props;
|
|
de_names = de_list->names;
|
|
de_count = de_list->count;
|
|
de_id = 0;
|
|
auth_fails = 0;
|
|
/* verifies if we can access the console with enough privileges */
|
|
console = fopen(LY_CONSOLE_DEV, "w");
|
|
|
|
if(!console)
|
|
{
|
|
fprintf(stderr, "%s\n", LY_ERR_FD);
|
|
fprintf(stderr, "%s\n", LY_ERR_FD_ADVICE);
|
|
return 0;
|
|
}
|
|
|
|
kernel_log(0);
|
|
/* initializes ncurses UI */
|
|
init_ncurses(console);
|
|
init_form(&form, de_names, de_count, &de_id);
|
|
init_win(&win, &form);
|
|
init_scene(&win, &form);
|
|
init_draw(&win, &form);
|
|
close(fileno(console));
|
|
/* enables insertion mode */
|
|
form_driver(form.form, REQ_INS_MODE);
|
|
/* makes the password field active by default */
|
|
set_current_field(form.form, form.fields[4]);
|
|
form_driver(form.form, REQ_END_LINE);
|
|
|
|
while((input_key = wgetch(win.win)))
|
|
{
|
|
form.active = current_field(form.form);
|
|
|
|
switch(input_key)
|
|
{
|
|
case KEY_ENTER_ASCII:
|
|
if(form.active == form.fields[4])
|
|
{
|
|
/* checks for buffer errors */
|
|
if(form_driver(form.form, REQ_VALIDATION) != E_OK)
|
|
{
|
|
error_print(LY_ERR_NC_BUFFER);
|
|
break;
|
|
}
|
|
|
|
/* stores the user inputs in processing buffers */
|
|
username = trim(field_buffer(form.fields[2], 0));
|
|
password = trim(field_buffer(form.fields[4], 0));
|
|
cmd = de_props[de_id].cmd;
|
|
type = de_props[de_id].type;
|
|
|
|
/* saves the username and DE if enabled */
|
|
if(LY_CFG_WRITE_SAVE)
|
|
{
|
|
FILE* file = fopen(LY_CFG_SAVE, "ab+");
|
|
file = fopen(LY_CFG_SAVE, "wb");
|
|
fprintf(file, "%s\n%d", username, de_id);
|
|
fclose(file);
|
|
}
|
|
|
|
/* logs in and suspends ncurses mode if successful */
|
|
fail = start_env(username, password, cmd, type);
|
|
/* clears the password */
|
|
set_field_buffer(form.fields[4], 0, "");
|
|
|
|
if(fail)
|
|
{
|
|
++auth_fails;
|
|
|
|
if(auth_fails > (LY_CFG_AUTH_TRIG - 1))
|
|
{
|
|
cascade();
|
|
}
|
|
}
|
|
else if(LY_CFG_CLR_USR)
|
|
{
|
|
/* clears the username */
|
|
set_field_buffer(form.fields[2], 0, "");
|
|
/* sets cursor to the login field */
|
|
set_current_field(form.form, form.fields[2]);
|
|
break;
|
|
}
|
|
|
|
/* sets cursor to the password field */
|
|
set_current_field(form.form, form.fields[4]);
|
|
break;
|
|
}
|
|
|
|
case KEY_DOWN:
|
|
form_driver(form.form, REQ_NEXT_FIELD);
|
|
form_driver(form.form, REQ_END_LINE);
|
|
break;
|
|
|
|
case KEY_UP:
|
|
form_driver(form.form, REQ_PREV_FIELD);
|
|
form_driver(form.form, REQ_END_LINE);
|
|
break;
|
|
|
|
case KEY_RIGHT:
|
|
if(form.active == form.fields[0])
|
|
{
|
|
de_id = ((de_id + 1) == de_count) ? 0 : de_id + 1;
|
|
form_driver(form.form, REQ_NEXT_CHOICE);
|
|
}
|
|
else
|
|
{
|
|
form_driver(form.form, REQ_NEXT_CHAR);
|
|
}
|
|
|
|
break;
|
|
|
|
case KEY_LEFT:
|
|
if(form.active == form.fields[0])
|
|
{
|
|
de_id = (de_id == 0) ? (de_count - 1) : de_id - 1;
|
|
form_driver(form.form, REQ_PREV_CHOICE);
|
|
}
|
|
else
|
|
{
|
|
form_driver(form.form, REQ_PREV_CHAR);
|
|
}
|
|
|
|
break;
|
|
|
|
case KEY_BACKSPACE_ASCII:
|
|
case KEY_BACKSPACE:
|
|
form_driver(form.form, REQ_DEL_PREV);
|
|
form_driver(form.form, REQ_END_LINE);
|
|
break;
|
|
|
|
case KEY_DC:
|
|
form_driver(form.form, REQ_DEL_CHAR);
|
|
break;
|
|
|
|
case KEY_F(1):
|
|
end_form(&form);
|
|
endwin();
|
|
free_list(de_list);
|
|
execl(LY_CMD_HALT, LY_CMD_HALT, "-h", "now", NULL);
|
|
break;
|
|
|
|
case KEY_F(2):
|
|
end_form(&form);
|
|
endwin();
|
|
free_list(de_list);
|
|
execl(LY_CMD_HALT, LY_CMD_HALT, "-r", "now", NULL);
|
|
break;
|
|
|
|
default:
|
|
form_driver(form.form, input_key);
|
|
break;
|
|
}
|
|
}
|
|
|
|
kernel_log(1);
|
|
fclose(console);
|
|
free_list(de_list);
|
|
end_form(&form);
|
|
endwin();
|
|
return 0;
|
|
}
|