26 Commits

Author SHA1 Message Date
cylgom
7fd849d81e add ctrl-u input clearing 2020-02-03 08:51:05 +01:00
cylgom
8b5ad0b1b1 clear password instead of free 2020-02-03 08:39:15 +01:00
cylgom
2892559ea2 fix password not being cleared when blank_password is set 2020-02-03 08:34:42 +01:00
Érico Nogueira Rolim
b2c1ef5c50 add wayland specifier to session names (#162)
Create a config option to force ly to add " (Wayland)" to session
names, as long as those names don't already contain the string.
2020-02-03 07:20:47 +01:00
cylgom
a36f70ecb2 fix wayland sessions 2020-02-01 20:16:26 +01:00
cylgom
2101f5bde0 remove developement comment (#140) 2020-02-01 19:26:06 +01:00
cylgom
7296da456f put xauthority file in XDG_CONFIG if specified 2020-02-01 19:01:51 +01:00
Érico Nogueira Rolim
30c2bf34b9 Make the project compilable with clang. (#163)
Clang generates more warning messages, such as pointing out a lack
of newline at end of file and issues with the size of a strncopy.

Moving -Wno-unused-parameter to the end of the flags avoids it being
overwritten by -Wextra.

Removing -Werror avoids compilation errors that may arise from new
compiler warnings that might come from newer versions of compilers.
2020-02-01 18:23:25 +01:00
Deven Blake
8d85e27194 Adding desktops that are tested (#168)
@RandomGuyDTB tested the latest versions of MaXX Interactive Desktop and GNU WindowMaker
2020-02-01 18:16:23 +01:00
mozartilize
48cf7f5827 fix hidden cursor after logout (#172) 2020-02-01 18:14:13 +01:00
Iván
aaa34e09da fix typo in spanish translation (#159) 2019-12-16 15:03:55 +01:00
cylgom
55fcacb27f document libpam0g-dev dependency for debian-based distros (#101) 2019-12-14 12:30:02 +01:00
cylgom
f593339cd4 add install without conf target 2019-12-14 12:23:43 +01:00
Iván
dda5a0c688 Translate Ly to Spanish (#150)
Pending to test.
2019-12-14 12:16:45 +01:00
cylgom
676cbf55a8 fix language loading 2019-12-14 12:12:50 +01:00
Stuart Reilly
40fb8659ba Remove /usr/bin/env from default path (#158) 2019-12-14 11:58:30 +01:00
Mateusz Piotrowski
216c6fb63b Mention that GNU make is required (#139)
The current makefile is not compatible with bmake,
which is the default make on FreeBSD.
2019-12-14 11:50:17 +01:00
Stanislav Láznička
e4afa78d14 Fix building by explicitly casting const out in config.c (#155) 2019-12-06 16:15:08 +01:00
Stanislav Láznička
c98bd74a8e Implement utmp audit (#133)
Implements utmp audit required by policykit.

This commit also flattens the pidtree for the DM by starting the
display environment directly in the first fork which already should
have the environment ready for this purpose. This is with the
exception of xorg environments where this can't be done that easily.
2019-12-06 16:10:27 +01:00
Roosemberth Palacios
cba0333fc5 Alloc passing the path to the configuration file as an argument (#134)
Signed-off-by: Roosembert Palacios <roosembert.palacios@epfl.ch>
2019-10-31 13:54:45 +01:00
Roosemberth Palacios
38fefffdf6 login.c: Do not overwrite the PATH variable if config.path element is empty (#135)
This allows disabling the feature if PATH was already set (e.g. by the systemd session
slice) and the user wishes to honor that.

Signed-off-by: Roosembert Palacios <roosembert.palacios@epfl.ch>
2019-10-31 00:03:35 +01:00
Roosemberth Palacios
1796a355bc Makefile: Add config option to allow specifying a separate data directory (#136)
This allows the user to specify a different directory to store static files, such as
translations and other resources.

Signed-off-by: Roosembert Palacios <roosembert.palacios@epfl.ch>
2019-10-27 16:49:55 +01:00
Stanislav Láznička
d839a92296 cosmetic changes + enter behavior (#126)
* remove trailing whitespace

* always submit password on enter

Moves the keypress logic for keypresses from if-else statements
to switches, adds non-contextual behavior on pressing enter

* wrap pam actions and handle errors at on spot

* init all of text struct in input_text()

This gets rid off valgrind warning on unitialized variables
2019-10-04 20:50:02 +02:00
Stanislav Láznička
0b467a95b3 print hostname in info lane on start (#127)
hostname was set in the info_line and unset right after that
2019-10-04 20:41:56 +02:00
cylgom
7485d89a4a fix remotes dependant submodules 2019-09-22 16:57:03 +02:00
cylgom
62c3d70496 set LANG 2019-09-21 18:34:03 +02:00
12 changed files with 290 additions and 135 deletions

View File

@@ -1,7 +1,7 @@
NAME = ly NAME = ly
CC = gcc CC = gcc
FLAGS = -std=c99 -pedantic -g FLAGS = -std=c99 -pedantic -g
FLAGS+= -Wall -Wno-unused-parameter -Wextra -Werror=vla -Werror FLAGS+= -Wall -Wextra -Werror=vla -Wno-unused-parameter
#FLAGS+= -DDEBUG #FLAGS+= -DDEBUG
FLAGS+= -DGIT_VERSION_STRING=\"$(shell git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g')\" FLAGS+= -DGIT_VERSION_STRING=\"$(shell git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g')\"
LINK = -lpam -lxcb LINK = -lpam -lxcb
@@ -20,6 +20,9 @@ SUBD = sub
RESD = res RESD = res
TESTD = tests TESTD = tests
DATADIR ?= ${DESTDIR}/etc/ly
FLAGS+= -DDATADIR=\"$(DATADIR)\"
INCL = -I$(SRCD) INCL = -I$(SRCD)
INCL+= -I$(SUBD)/ctypes INCL+= -I$(SUBD)/ctypes
INCL+= -I$(SUBD)/argoat/src INCL+= -I$(SUBD)/argoat/src
@@ -70,16 +73,27 @@ install: $(BIND)/$(NAME)
@echo "installing" @echo "installing"
@install -dZ ${DESTDIR}/etc/ly @install -dZ ${DESTDIR}/etc/ly
@install -DZ $(BIND)/$(NAME) -t ${DESTDIR}/usr/bin @install -DZ $(BIND)/$(NAME) -t ${DESTDIR}/usr/bin
@install -DZ $(RESD)/xsetup.sh -t ${DESTDIR}/etc/ly
@install -DZ $(RESD)/wsetup.sh -t ${DESTDIR}/etc/ly
@install -DZ $(RESD)/config.ini -t ${DESTDIR}/etc/ly @install -DZ $(RESD)/config.ini -t ${DESTDIR}/etc/ly
@install -dZ ${DESTDIR}/etc/ly/lang @install -DZ $(RESD)/xsetup.sh -t $(DATADIR)
@install -DZ $(RESD)/lang/* -t ${DESTDIR}/etc/ly/lang @install -DZ $(RESD)/wsetup.sh -t $(DATADIR)
@install -dZ $(DATADIR)/lang
@install -DZ $(RESD)/lang/* -t $(DATADIR)/lang
@install -DZ $(RESD)/ly.service -t ${DESTDIR}/usr/lib/systemd/system
installnoconf: $(BIND)/$(NAME)
@echo "installing without the configuration file"
@install -dZ ${DESTDIR}/etc/ly
@install -DZ $(BIND)/$(NAME) -t ${DESTDIR}/usr/bin
@install -DZ $(RESD)/xsetup.sh -t $(DATADIR)
@install -DZ $(RESD)/wsetup.sh -t $(DATADIR)
@install -dZ $(DATADIR)/lang
@install -DZ $(RESD)/lang/* -t $(DATADIR)/lang
@install -DZ $(RESD)/ly.service -t ${DESTDIR}/usr/lib/systemd/system @install -DZ $(RESD)/ly.service -t ${DESTDIR}/usr/lib/systemd/system
uninstall: uninstall:
@echo "uninstalling" @echo "uninstalling"
@rm -rf ${DESTDIR}/etc/ly @rm -rf ${DESTDIR}/etc/ly
@rm -rf $(DATADIR)
@rm -f ${DESTDIR}/usr/bin/ly @rm -f ${DESTDIR}/usr/bin/ly
@rm -f ${DESTDIR}/usr/lib/systemd/system/ly.service @rm -f ${DESTDIR}/usr/lib/systemd/system/ly.service
@@ -93,7 +107,7 @@ remotes:
@git remote add github git@github.com:cylgom/$(NAME).git @git remote add github git@github.com:cylgom/$(NAME).git
@git remote add gitea ssh://git@git.cylgom.net:2999/cylgom/$(NAME).git @git remote add gitea ssh://git@git.cylgom.net:2999/cylgom/$(NAME).git
github: remotes github:
@echo "sourcing submodules from https://github.com" @echo "sourcing submodules from https://github.com"
@cp .github .gitmodules @cp .github .gitmodules
@git submodule sync @git submodule sync
@@ -101,7 +115,7 @@ github: remotes
@cd $(SUBD)/argoat && make github @cd $(SUBD)/argoat && make github
@git submodule update --init --recursive --remote @git submodule update --init --recursive --remote
gitea: remotes gitea:
@echo "sourcing submodules from https://git.cylgom.net" @echo "sourcing submodules from https://git.cylgom.net"
@cp .gitea .gitmodules @cp .gitea .gitmodules
@git submodule sync @git submodule sync

View File

@@ -7,7 +7,7 @@ Ly is a lightweight TUI (ncurses-like) display manager for Linux and BSD.
## Dependencies ## Dependencies
- a C99 compiler (tested with tcc and gcc) - a C99 compiler (tested with tcc and gcc)
- a C standard library - a C standard library
- make - GNU make
- pam - pam
- xcb - xcb
- xorg - xorg
@@ -16,6 +16,9 @@ Ly is a lightweight TUI (ncurses-like) display manager for Linux and BSD.
- tput - tput
- shutdown - shutdown
### Debian-based distros
- libpam0g-dev
## Support ## Support
The following desktop environments were tested with success The following desktop environments were tested with success
- budgie - budgie
@@ -31,6 +34,8 @@ The following desktop environments were tested with success
- sway - sway
- xfce - xfce
- pantheon - pantheon
- maxx
- windowmaker
Ly should work with any X desktop environment, and provides Ly should work with any X desktop environment, and provides
basic wayland support (sway works very well, for example). basic wayland support (sway works very well, for example).

View File

@@ -57,7 +57,7 @@
#min_refresh_delta = 5 #min_refresh_delta = 5
# default path # default path
#path = /sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/env #path = /sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin
# command executed when pressing F2 # command executed when pressing F2
#restart_cmd = /sbin/shutdown -r now #restart_cmd = /sbin/shutdown -r now
@@ -83,6 +83,9 @@
# wayland setup command # wayland setup command
#wayland_cmd = /etc/ly/wsetup.sh #wayland_cmd = /etc/ly/wsetup.sh
# add wayland specifier to session names
#wayland_specifier = false
# wayland desktop environments # wayland desktop environments
#waylandsessions = /usr/share/wayland-sessions #waylandsessions = /usr/share/wayland-sessions

45
res/lang/es.ini Normal file
View File

@@ -0,0 +1,45 @@
capslock = Bloq Mayús
err_alloc = asignación de memoria fallida
err_bounds = índice fuera de límites
err_chdir = error al abrir la carpeta home
err_console_dev = error al acceder a la consola
err_dgn_oob = mensaje de registro
err_domain = dominio inválido
err_hostname = error al obtener el nombre de host
err_mlock = error al bloquear la contraseña de memoria
err_null = puntero nulo
err_pam = error en la transacción pam
err_pam_abort = transacción pam abortada
err_pam_acct_expired = cuenta expirada
err_pam_auth = error de autenticación
err_pam_authinfo_unavail = error al obtener información del usuario
err_pam_authok_reqd = token expirado
err_pam_buf = error de la memoria intermedia
err_pam_cred_err = error al establecer la credenciales
err_pam_cred_expired = credenciales expiradas
err_pam_cred_insufficient = credenciales insuficientes
err_pam_cred_unavail = error al obtener credenciales
err_pam_maxtries = se ha alcanzado el límite de intentos
err_pam_perm_denied = permiso denegado
err_pam_session = error de sesión
err_pam_sys = error de sistema
err_pam_user_unknown = usuario desconocido
err_path = error al establecer la ruta
err_perm_dir = error al cambiar el directorio actual
err_perm_group = error al degradar los permisos del grupo
err_perm_user = error al degradar los permisos del usuario
err_pwnam = error al obtener la información del usuario
err_user_gid = error al establecer el GID del usuario
err_user_init = errpr al inicializar usuario
err_user_uid = error al establecer el UID del usuario
err_xsessions_dir = error al buscar la carpeta de sesiones
err_xsessions_open = error al abrir la carpeta de sesiones
f1 = F1 apagar
f2 = F2 reiniciar
login = iniciar sesion:
logout = cerrar sesion
numlock = Bloq Num
password = contraseña:
shell = shell
wayland = wayland
xinitrc = xinitrc

View File

@@ -9,7 +9,7 @@
#include <unistd.h> #include <unistd.h>
#ifndef DEBUG #ifndef DEBUG
#define INI_LANG "/etc/ly/lang/%s.ini" #define INI_LANG DATADIR "/lang/%s.ini"
#define INI_CONFIG "/etc/ly/config.ini" #define INI_CONFIG "/etc/ly/config.ini"
#else #else
#define INI_LANG "../res/lang/%s.ini" #define INI_LANG "../res/lang/%s.ini"
@@ -146,8 +146,12 @@ void lang_load()
} }
} }
void config_load() void config_load(const char *cfg_path)
{ {
if (cfg_path == NULL)
{
cfg_path = INI_CONFIG;
}
// must be alphabetically sorted // must be alphabetically sorted
struct configator_param map_no_section[] = struct configator_param map_no_section[] =
{ {
@@ -156,7 +160,7 @@ void config_load()
{"asterisk", &config.asterisk, config_handle_char}, {"asterisk", &config.asterisk, config_handle_char},
{"bg", &config.bg, config_handle_u8}, {"bg", &config.bg, config_handle_u8},
{"blank_box", &config.blank_box, config_handle_bool}, {"blank_box", &config.blank_box, config_handle_bool},
{"blank_password", &config.blank_box, config_handle_bool}, {"blank_password", &config.blank_password, config_handle_bool},
{"console_dev", &config.console_dev, config_handle_str}, {"console_dev", &config.console_dev, config_handle_str},
{"default_input", &config.default_input, config_handle_u8}, {"default_input", &config.default_input, config_handle_u8},
{"fg", &config.fg, config_handle_u8}, {"fg", &config.fg, config_handle_u8},
@@ -180,6 +184,7 @@ void config_load()
{"term_reset_cmd", &config.term_reset_cmd, config_handle_str}, {"term_reset_cmd", &config.term_reset_cmd, config_handle_str},
{"tty", &config.tty, config_handle_u8}, {"tty", &config.tty, config_handle_u8},
{"wayland_cmd", &config.wayland_cmd, config_handle_str}, {"wayland_cmd", &config.wayland_cmd, config_handle_str},
{"wayland_specifier", &config.wayland_specifier, config_handle_bool},
{"waylandsessions", &config.waylandsessions, config_handle_str}, {"waylandsessions", &config.waylandsessions, config_handle_str},
{"x_cmd", &config.x_cmd, config_handle_str}, {"x_cmd", &config.x_cmd, config_handle_str},
{"x_cmd_setup", &config.x_cmd_setup, config_handle_str}, {"x_cmd_setup", &config.x_cmd_setup, config_handle_str},
@@ -202,7 +207,7 @@ void config_load()
config.sections = sections; config.sections = sections;
config.sections_len = sections_len; config.sections_len = sections_len;
configator(&config, INI_CONFIG); configator(&config, (char *) cfg_path);
} }
void lang_defaults() void lang_defaults()
@@ -263,7 +268,7 @@ void config_defaults()
config.blank_box = true; config.blank_box = true;
config.blank_password = false; config.blank_password = false;
config.console_dev = strdup("/dev/console"); config.console_dev = strdup("/dev/console");
config.default_input = 2; config.default_input = PASSWORD_INPUT;
config.fg = 9; config.fg = 9;
config.hide_borders = false; config.hide_borders = false;
config.input_len = 34; config.input_len = 34;
@@ -276,7 +281,7 @@ void config_defaults()
config.max_password_len = 255; config.max_password_len = 255;
config.mcookie_cmd = strdup("/usr/bin/mcookie"); config.mcookie_cmd = strdup("/usr/bin/mcookie");
config.min_refresh_delta = 5; config.min_refresh_delta = 5;
config.path = strdup("/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/env"); config.path = strdup("/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin");
config.restart_cmd = strdup("/sbin/shutdown -r now"); config.restart_cmd = strdup("/sbin/shutdown -r now");
config.save = true; config.save = true;
config.save_file = strdup("/etc/ly/save"); config.save_file = strdup("/etc/ly/save");
@@ -284,10 +289,11 @@ void config_defaults()
config.shutdown_cmd = strdup("/sbin/shutdown -a now"); config.shutdown_cmd = strdup("/sbin/shutdown -a now");
config.term_reset_cmd = strdup("/usr/bin/tput reset"); config.term_reset_cmd = strdup("/usr/bin/tput reset");
config.tty = 2; config.tty = 2;
config.wayland_cmd = strdup("/etc/ly/wsetup.sh"); config.wayland_cmd = strdup(DATADIR "/wsetup.sh");
config.wayland_specifier = false;
config.waylandsessions = strdup("/usr/share/wayland-sessions"); config.waylandsessions = strdup("/usr/share/wayland-sessions");
config.x_cmd = strdup("/usr/bin/X"); config.x_cmd = strdup("/usr/bin/X");
config.x_cmd_setup = strdup("/etc/ly/xsetup.sh"); config.x_cmd_setup = strdup(DATADIR "/xsetup.sh");
config.xauth_cmd = strdup("/usr/bin/xauth"); config.xauth_cmd = strdup("/usr/bin/xauth");
config.xsessions = strdup("/usr/share/xsessions"); config.xsessions = strdup("/usr/share/xsessions");
} }

View File

@@ -3,6 +3,12 @@
#include "ctypes.h" #include "ctypes.h"
enum INPUTS {
SESSION_SWITCH,
LOGIN_INPUT,
PASSWORD_INPUT,
};
struct lang struct lang
{ {
char* capslock; char* capslock;
@@ -83,6 +89,7 @@ struct config
char* term_reset_cmd; char* term_reset_cmd;
u8 tty; u8 tty;
char* wayland_cmd; char* wayland_cmd;
bool wayland_specifier;
char* waylandsessions; char* waylandsessions;
char* x_cmd; char* x_cmd;
char* x_cmd_setup; char* x_cmd_setup;
@@ -95,7 +102,7 @@ extern struct config config;
void config_handle_str(void* data, char** pars, const int pars_count); void config_handle_str(void* data, char** pars, const int pars_count);
void lang_load(); void lang_load();
void config_load(); void config_load(const char *cfg_path);
void lang_defaults(); void lang_defaults();
void config_defaults(); void config_defaults();
void lang_free(); void lang_free();

View File

@@ -28,7 +28,6 @@ void draw_init(struct term_buf* buf)
buf->width = tb_width(); buf->width = tb_width();
buf->height = tb_height(); buf->height = tb_height();
hostname(&buf->info_line); hostname(&buf->info_line);
buf->info_line = NULL;
u16 len_login = strlen(lang.login); u16 len_login = strlen(lang.login);
u16 len_password = strlen(lang.password); u16 len_password = strlen(lang.password);

View File

@@ -115,6 +115,8 @@ void input_text(struct text* target, u64 len)
target->end = target->text; target->end = target->text;
target->visible_start = target->text; target->visible_start = target->text;
target->len = len; target->len = len;
target->x = 0;
target->y = 0;
} }
void input_desktop_free(struct desktop* target) void input_desktop_free(struct desktop* target)
@@ -256,3 +258,11 @@ void input_text_backspace(struct text* target)
input_text_delete(target); input_text_delete(target);
} }
} }
void input_text_clear(struct text* target)
{
memset(target->text, 0, target->len + 1);
target->cur = target->text;
target->end = target->text;
target->visible_start = target->text;
}

View File

@@ -50,5 +50,6 @@ void input_text_left(struct text* target);
void input_text_write(struct text* target, char ascii); void input_text_write(struct text* target, char ascii);
void input_text_delete(struct text* target); void input_text_delete(struct text* target);
void input_text_backspace(struct text* target); void input_text_backspace(struct text* target);
void input_text_clear(struct text* target);
#endif #endif

View File

@@ -18,6 +18,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <utmp.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
int get_free_display() int get_free_display()
@@ -204,11 +205,11 @@ void pam_diagnose(int error, struct term_buf* buf)
dgn_throw(DGN_PAM); dgn_throw(DGN_PAM);
} }
void env_init(struct passwd* pwd, const char* display_name) void env_init(struct passwd* pwd)
{ {
extern char** environ; extern char** environ;
// term
char* term = getenv("TERM"); char* term = getenv("TERM");
char* lang = getenv("LANG");
// clean env // clean env
environ[0] = NULL; environ[0] = NULL;
@@ -226,14 +227,17 @@ void env_init(struct passwd* pwd, const char* display_name)
setenv("SHELL", pwd->pw_shell, 1); setenv("SHELL", pwd->pw_shell, 1);
setenv("USER", pwd->pw_name, 1); setenv("USER", pwd->pw_name, 1);
setenv("LOGNAME", pwd->pw_name, 1); setenv("LOGNAME", pwd->pw_name, 1);
setenv("DISPLAY", display_name, 1); setenv("LANG", lang, 1);
// path // Set PATH if specified in the configuration
int ok = setenv("PATH", config.path, 1); if (strlen(config.path))
if (ok != 0)
{ {
dgn_throw(DGN_PATH); int ok = setenv("PATH", config.path, 1);
if (ok != 0)
{
dgn_throw(DGN_PATH);
}
} }
} }
@@ -250,7 +254,7 @@ void env_xdg(const char* tty_id, const enum display_server display_server)
{ {
case DS_WAYLAND: case DS_WAYLAND:
{ {
setenv("XDG_SESSION_TYPE", "wayland", 0); setenv("XDG_SESSION_TYPE", "wayland", 1);
break; break;
} }
case DS_SHELL: case DS_SHELL:
@@ -267,11 +271,44 @@ void env_xdg(const char* tty_id, const enum display_server display_server)
} }
} }
void xauth(const char* display_name, const char* shell, const char* home) void add_utmp_entry(
struct utmp *entry,
char *username,
pid_t display_pid
) {
entry->ut_type = USER_PROCESS;
entry->ut_pid = display_pid;
strcpy(entry->ut_line, ttyname(STDIN_FILENO) + strlen("/dev/"));
/* only correct for ptys named /dev/tty[pqr][0-9a-z] */
strcpy(entry->ut_id, ttyname(STDIN_FILENO) + strlen("/dev/tty"));
time((long int *) &entry->ut_time);
strncpy(entry->ut_user, username, UT_NAMESIZE);
memset(entry->ut_host, 0, UT_HOSTSIZE);
entry->ut_addr = 0;
setutent();
pututline(entry);
}
void remove_utmp_entry(struct utmp *entry) {
entry->ut_type = DEAD_PROCESS;
memset(entry->ut_line, 0, UT_LINESIZE);
entry->ut_time = 0;
memset(entry->ut_user, 0, UT_NAMESIZE);
setutent();
pututline(entry);
endutent();
}
void xauth(const char* display_name, const char* shell, const char* dir)
{ {
char xauthority[256]; char xauthority[256];
snprintf(xauthority, 256, "%s/%s", home, ".lyxauth"); snprintf(xauthority, 256, "%s/%s", dir, ".lyxauth");
setenv("XAUTHORITY", xauthority, 1); setenv("XAUTHORITY", xauthority, 1);
setenv("DISPLAY", display_name, 1);
FILE* fp = fopen(xauthority, "ab+"); FILE* fp = fopen(xauthority, "ab+");
@@ -302,14 +339,21 @@ void xauth(const char* display_name, const char* shell, const char* home)
void xorg( void xorg(
struct passwd* pwd, struct passwd* pwd,
const char* display_name,
const char* vt, const char* vt,
const char* desktop_cmd) const char* desktop_cmd)
{ {
reset_terminal(pwd);
// generate xauthority file // generate xauthority file
xauth(display_name, pwd->pw_shell, pwd->pw_dir); const char* xauth_dir = getenv("XDG_CONFIG_HOME");
if ((xauth_dir == NULL) || (*xauth_dir == '\0'))
{
xauth_dir = pwd->pw_dir;
}
char display_name[4];
snprintf(display_name, 3, ":%d", get_free_display());
xauth(display_name, pwd->pw_shell, xauth_dir);
// start xorg // start xorg
pid_t pid = fork(); pid_t pid = fork();
@@ -361,7 +405,6 @@ void xorg(
int status; int status;
waitpid(xorg_pid, &status, 0); waitpid(xorg_pid, &status, 0);
reset_terminal(pwd);
xcb_disconnect(xcb); xcb_disconnect(xcb);
kill(pid, 0); kill(pid, 0);
@@ -376,50 +419,47 @@ void wayland(
struct passwd* pwd, struct passwd* pwd,
const char* desktop_cmd) const char* desktop_cmd)
{ {
reset_terminal(pwd);
pid_t pid = fork();
if (pid == 0)
{
char cmd[1024];
snprintf(cmd, 1024, "%s %s", config.wayland_cmd, desktop_cmd);
execl(pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL);
exit(EXIT_SUCCESS);
}
int status; char cmd[1024];
waitpid(pid, &status, 0); snprintf(cmd, 1024, "%s %s", config.wayland_cmd, desktop_cmd);
reset_terminal(pwd); execl(pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL);
} }
void shell(struct passwd* pwd) void shell(struct passwd* pwd)
{ {
reset_terminal(pwd); const char* pos = strrchr(pwd->pw_shell, '/');
pid_t pid = fork(); char args[1024];
args[0] = '-';
if (pid == 0) if (pos != NULL)
{ {
const char* pos = strrchr(pwd->pw_shell, '/'); pos = pos + 1;
char args[1024]; }
args[0] = '-'; else
{
if (pos != NULL) pos = pwd->pw_shell;
{
pos = pos + 1;
}
else
{
pos = pwd->pw_shell;
}
strncpy(args + 1, pos, 1024);
execl(pwd->pw_shell, args, NULL);
exit(EXIT_SUCCESS);
} }
int status; strncpy(args + 1, pos, 1023);
waitpid(pid, &status, 0); execl(pwd->pw_shell, args, NULL);
reset_terminal(pwd); }
// pam_do performs the pam action specified in pam_action
// on pam_action fail, call diagnose and end pam session
int pam_do(
int (pam_action)(struct pam_handle *, int),
struct pam_handle *handle,
int flags,
struct term_buf *buf)
{
int status = pam_action(handle, flags);
if (status != PAM_SUCCESS) {
pam_diagnose(status, buf);
pam_end(handle, status);
}
return status;
} }
void auth( void auth(
@@ -444,45 +484,36 @@ void auth(
return; return;
} }
ok = pam_authenticate(handle, 0); ok = pam_do(pam_authenticate, handle, 0, buf);
if (ok != PAM_SUCCESS) if (ok != PAM_SUCCESS)
{ {
pam_diagnose(ok, buf);
pam_end(handle, ok);
return; return;
} }
ok = pam_acct_mgmt(handle, 0); ok = pam_do(pam_acct_mgmt, handle, 0, buf);
if (ok != PAM_SUCCESS) if (ok != PAM_SUCCESS)
{ {
pam_diagnose(ok, buf);
pam_end(handle, ok);
return; return;
} }
ok = pam_setcred(handle, PAM_ESTABLISH_CRED); ok = pam_do(pam_setcred, handle, PAM_ESTABLISH_CRED, buf);
if (ok != PAM_SUCCESS) if (ok != PAM_SUCCESS)
{ {
pam_diagnose(ok, buf);
pam_end(handle, ok);
return; return;
} }
ok = pam_open_session(handle, 0); ok = pam_do(pam_open_session, handle, 0, buf);
if (ok != PAM_SUCCESS) if (ok != PAM_SUCCESS)
{ {
pam_diagnose(ok, buf);
pam_end(handle, ok);
return; return;
} }
// clear the credentials // clear the credentials
input_text_free(password); input_text_clear(password);
input_text(password, config.max_password_len);
// get passwd structure // get passwd structure
struct passwd* pwd = getpwnam(login->text); struct passwd* pwd = getpwnam(login->text);
@@ -546,17 +577,14 @@ void auth(
} }
// get a display // get a display
int display_id = get_free_display();
char display_name[3];
char tty_id [3]; char tty_id [3];
char vt[5]; char vt[5];
snprintf(display_name, 3, ":%d", display_id);
snprintf(tty_id, 3, "%d", config.tty); snprintf(tty_id, 3, "%d", config.tty);
snprintf(vt, 5, "vt%d", config.tty); snprintf(vt, 5, "vt%d", config.tty);
// set env // set env
env_init(pwd, display_name); env_init(pwd);
if (dgn_catch()) if (dgn_catch())
{ {
@@ -583,6 +611,7 @@ void auth(
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
reset_terminal(pwd);
switch (desktop->display_server[desktop->cur]) switch (desktop->display_server[desktop->cur])
{ {
case DS_WAYLAND: case DS_WAYLAND:
@@ -598,7 +627,7 @@ void auth(
case DS_XINITRC: case DS_XINITRC:
case DS_XORG: case DS_XORG:
{ {
xorg(pwd, display_name, vt, desktop->cmd[desktop->cur]); xorg(pwd, vt, desktop->cmd[desktop->cur]);
break; break;
} }
} }
@@ -606,9 +635,16 @@ void auth(
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
// add utmp audit
struct utmp entry;
add_utmp_entry(&entry, pwd->pw_name, pid);
// wait for the session to stop // wait for the session to stop
int status; int status;
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
remove_utmp_entry(&entry);
reset_terminal(pwd);
// reinit termbox // reinit termbox
tb_init(); tb_init();
@@ -620,21 +656,17 @@ void auth(
desktop_load(desktop); desktop_load(desktop);
// close pam session // close pam session
ok = pam_close_session(handle, 0); ok = pam_do(pam_close_session, handle, 0, buf);
if (ok != PAM_SUCCESS) if (ok != PAM_SUCCESS)
{ {
pam_diagnose(ok, buf);
pam_end(handle, ok);
return; return;
} }
ok = pam_setcred(handle, PAM_DELETE_CRED); ok = pam_do(pam_setcred, handle, PAM_DELETE_CRED, buf);
if (ok != PAM_SUCCESS) if (ok != PAM_SUCCESS)
{ {
pam_diagnose(ok, buf);
pam_end(handle, ok);
return; return;
} }
@@ -645,3 +677,4 @@ void auth(
pam_diagnose(ok, buf); pam_diagnose(ok, buf);
} }
} }

View File

@@ -16,10 +16,9 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#define ARG_COUNT 5 #define ARG_COUNT 7
// things you can define: // things you can define:
// GIT_VERSION_STRING // GIT_VERSION_STRING
// RUNIT
// global // global
struct lang lang; struct lang lang;
@@ -47,7 +46,7 @@ void log_init(char** log)
log[DGN_NULL] = lang.err_null; log[DGN_NULL] = lang.err_null;
log[DGN_ALLOC] = lang.err_alloc; log[DGN_ALLOC] = lang.err_alloc;
log[DGN_BOUNDS] = lang.err_bounds; log[DGN_BOUNDS] = lang.err_bounds;
log[DGN_DOMAIN] = lang.err_domain; log[DGN_DOMAIN] = lang.err_domain;
log[DGN_MLOCK] = lang.err_mlock; log[DGN_MLOCK] = lang.err_mlock;
log[DGN_XSESSIONS_DIR] = lang.err_xsessions_dir; log[DGN_XSESSIONS_DIR] = lang.err_xsessions_dir;
log[DGN_XSESSIONS_OPEN] = lang.err_xsessions_open; log[DGN_XSESSIONS_OPEN] = lang.err_xsessions_open;
@@ -61,6 +60,11 @@ void log_init(char** log)
log[DGN_HOSTNAME] = lang.err_hostname; log[DGN_HOSTNAME] = lang.err_hostname;
} }
void arg_config(void* data, char** pars, const int pars_count)
{
*((char **)data) = *pars;
}
// ly! // ly!
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@@ -71,17 +75,13 @@ int main(int argc, char** argv)
config_defaults(); config_defaults();
lang_defaults(); lang_defaults();
config_load(); char *config_path = NULL;
if (strcmp(config.lang, "en") != 0)
{
lang_load();
}
// parse args // parse args
const struct argoat_sprig sprigs[ARG_COUNT] = const struct argoat_sprig sprigs[ARG_COUNT] =
{ {
{NULL, 0, NULL, NULL}, {NULL, 0, NULL, NULL},
{"config", 0, &config_path, arg_config},
{"c", 0, &config_path, arg_config},
{"help", 0, NULL, arg_help}, {"help", 0, NULL, arg_help},
{"h", 0, NULL, arg_help}, {"h", 0, NULL, arg_help},
{"version", 0, NULL, arg_version}, {"version", 0, NULL, arg_version},
@@ -106,6 +106,13 @@ int main(int argc, char** argv)
return 1; return 1;
} }
config_load(config_path);
if (strcmp(config.lang, "en") != 0)
{
lang_load();
}
void* input_structs[3] = void* input_structs[3] =
{ {
(void*) &desktop, (void*) &desktop,
@@ -196,45 +203,49 @@ int main(int argc, char** argv)
if (event.type == TB_EVENT_KEY) if (event.type == TB_EVENT_KEY)
{ {
if (event.key == TB_KEY_F1) switch (event.key)
{ {
case TB_KEY_F1:
shutdown = true; shutdown = true;
run = false;
break; break;
} case TB_KEY_F2:
else if (event.key == TB_KEY_F2)
{
reboot = true; reboot = true;
run = false;
break; break;
} case TB_KEY_CTRL_C:
else if (event.key == TB_KEY_CTRL_C) run = false;
{
break; break;
} case TB_KEY_CTRL_U:
else if ((event.key == TB_KEY_ARROW_UP) && (active_input > 0)) if (active_input > 0)
{ {
--active_input; input_text_clear(input_structs[active_input]);
update = true; }
} break;
else if (((event.key == TB_KEY_ARROW_DOWN) case TB_KEY_ARROW_UP:
|| (event.key == TB_KEY_ENTER)) if (active_input > 0)
&& (active_input < 2)) {
{ --active_input;
++active_input; update = true;
update = true; }
} break;
else if (event.key == TB_KEY_TAB) case TB_KEY_ARROW_DOWN:
{ if (active_input < 2)
{
++active_input;
update = true;
}
break;
case TB_KEY_TAB:
++active_input; ++active_input;
if (active_input > 2) if (active_input > 2)
{ {
active_input = 0; active_input = PASSWORD_INPUT;
} }
update = true; update = true;
} break;
else if (event.key == TB_KEY_ENTER) case TB_KEY_ENTER:
{
save(&desktop, &login); save(&desktop, &login);
auth(&desktop, &login, &password, &buf); auth(&desktop, &login, &password, &buf);
update = true; update = true;
@@ -242,12 +253,19 @@ int main(int argc, char** argv)
if (dgn_catch()) if (dgn_catch())
{ {
++auth_fails; ++auth_fails;
// move focus back to password input
active_input = PASSWORD_INPUT;
if (dgn_output_code() != DGN_PAM) if (dgn_output_code() != DGN_PAM)
{ {
buf.info_line = dgn_output_log(); buf.info_line = dgn_output_log();
} }
if (config.blank_password)
{
input_text_clear(&password);
}
dgn_reset(); dgn_reset();
} }
else else
@@ -256,13 +274,14 @@ int main(int argc, char** argv)
} }
load(&desktop, &login); load(&desktop, &login);
} system("tput cnorm");
else break;
{ default:
(*input_handles[active_input])( (*input_handles[active_input])(
input_structs[active_input], input_structs[active_input],
&event); &event);
update = true; update = true;
break;
} }
} }
} }

View File

@@ -95,6 +95,19 @@ void desktop_crawl(
strncat(path, dir_info->d_name, (sizeof (path)) - 1); strncat(path, dir_info->d_name, (sizeof (path)) - 1);
configator(&desktop_config, path); configator(&desktop_config, path);
// if these are wayland sessions, add " (Wayland)" to their names,
// as long as their names don't already contain that string
if (server == DS_WAYLAND && config.wayland_specifier)
{
const char wayland_specifier[] = " (Wayland)";
if (strstr(name, wayland_specifier) == NULL)
{
name = realloc(name, (strlen(name) + sizeof(wayland_specifier) + 1));
// using strcat is safe because the string is constant
strcat(name, wayland_specifier);
}
}
if ((name != NULL) && (exec != NULL)) if ((name != NULL) && (exec != NULL))
{ {
input_desktop_add(target, name, exec, server); input_desktop_add(target, name, exec, server);