mirror of https://github.com/fairyglade/ly.git
Partially rewrite utils.c
This commit is contained in:
parent
2fd2f77ac0
commit
40c7c27b88
298
src/config.zig
298
src/config.zig
|
@ -171,7 +171,8 @@ var lang_wayland: [:0]u8 = undefined;
|
||||||
var lang_xinitrc: [:0]u8 = undefined;
|
var lang_xinitrc: [:0]u8 = undefined;
|
||||||
|
|
||||||
pub fn config_load(cfg_path: []const u8) !void {
|
pub fn config_load(cfg_path: []const u8) !void {
|
||||||
var file = try std.fs.cwd().openFile(if (std.mem.eql(u8, cfg_path, "")) INI_CONFIG_PATH ++ "config.ini" else cfg_path, .{});
|
var file = try std.fs.cwd().openFile(if (cfg_path.len == 0) INI_CONFIG_PATH ++ "config.ini" else cfg_path, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
config_buffer = try main.allocator.alloc(u8, INI_CONFIG_MAX_SIZE);
|
config_buffer = try main.allocator.alloc(u8, INI_CONFIG_MAX_SIZE);
|
||||||
|
|
||||||
|
@ -197,45 +198,45 @@ pub fn config_load(cfg_path: []const u8) !void {
|
||||||
config_xauth_cmd = try interop.c_str(ly_config.ly.xauth_cmd);
|
config_xauth_cmd = try interop.c_str(ly_config.ly.xauth_cmd);
|
||||||
config_xsessions = try interop.c_str(ly_config.ly.xsessions);
|
config_xsessions = try interop.c_str(ly_config.ly.xsessions);
|
||||||
|
|
||||||
main.config.animate = ly_config.ly.animate;
|
main.c_config.animate = ly_config.ly.animate;
|
||||||
main.config.animation = ly_config.ly.animation;
|
main.c_config.animation = ly_config.ly.animation;
|
||||||
main.config.asterisk = ly_config.ly.asterisk;
|
main.c_config.asterisk = ly_config.ly.asterisk;
|
||||||
main.config.bg = ly_config.ly.bg;
|
main.c_config.bg = ly_config.ly.bg;
|
||||||
main.config.bigclock = ly_config.ly.bigclock;
|
main.c_config.bigclock = ly_config.ly.bigclock;
|
||||||
main.config.blank_box = ly_config.ly.blank_box;
|
main.c_config.blank_box = ly_config.ly.blank_box;
|
||||||
main.config.blank_password = ly_config.ly.blank_password;
|
main.c_config.blank_password = ly_config.ly.blank_password;
|
||||||
main.config.clock = config_clock.ptr;
|
main.c_config.clock = config_clock.ptr;
|
||||||
main.config.console_dev = config_console_dev.ptr;
|
main.c_config.console_dev = config_console_dev.ptr;
|
||||||
main.config.default_input = ly_config.ly.default_input;
|
main.c_config.default_input = ly_config.ly.default_input;
|
||||||
main.config.fg = ly_config.ly.fg;
|
main.c_config.fg = ly_config.ly.fg;
|
||||||
main.config.hide_borders = ly_config.ly.hide_borders;
|
main.c_config.hide_borders = ly_config.ly.hide_borders;
|
||||||
main.config.hide_f1_commands = ly_config.ly.hide_f1_commands;
|
main.c_config.hide_f1_commands = ly_config.ly.hide_f1_commands;
|
||||||
main.config.input_len = ly_config.ly.input_len;
|
main.c_config.input_len = ly_config.ly.input_len;
|
||||||
main.config.lang = config_lang.ptr;
|
main.c_config.lang = config_lang.ptr;
|
||||||
main.config.load = ly_config.ly.load;
|
main.c_config.load = ly_config.ly.load;
|
||||||
main.config.margin_box_h = ly_config.ly.margin_box_h;
|
main.c_config.margin_box_h = ly_config.ly.margin_box_h;
|
||||||
main.config.margin_box_v = ly_config.ly.margin_box_v;
|
main.c_config.margin_box_v = ly_config.ly.margin_box_v;
|
||||||
main.config.max_desktop_len = ly_config.ly.max_desktop_len;
|
main.c_config.max_desktop_len = ly_config.ly.max_desktop_len;
|
||||||
main.config.max_login_len = ly_config.ly.max_login_len;
|
main.c_config.max_login_len = ly_config.ly.max_login_len;
|
||||||
main.config.max_password_len = ly_config.ly.max_password_len;
|
main.c_config.max_password_len = ly_config.ly.max_password_len;
|
||||||
main.config.mcookie_cmd = config_mcookie_cmd.ptr;
|
main.c_config.mcookie_cmd = config_mcookie_cmd.ptr;
|
||||||
main.config.min_refresh_delta = ly_config.ly.min_refresh_delta;
|
main.c_config.min_refresh_delta = ly_config.ly.min_refresh_delta;
|
||||||
main.config.path = config_path.ptr;
|
main.c_config.path = config_path.ptr;
|
||||||
main.config.restart_cmd = config_restart_cmd.ptr;
|
main.c_config.restart_cmd = config_restart_cmd.ptr;
|
||||||
main.config.save = ly_config.ly.save;
|
main.c_config.save = ly_config.ly.save;
|
||||||
main.config.save_file = config_save_file.ptr;
|
main.c_config.save_file = config_save_file.ptr;
|
||||||
main.config.service_name = config_service_name.ptr;
|
main.c_config.service_name = config_service_name.ptr;
|
||||||
main.config.shutdown_cmd = config_shutdown_cmd.ptr;
|
main.c_config.shutdown_cmd = config_shutdown_cmd.ptr;
|
||||||
main.config.term_reset_cmd = config_term_reset_cmd.ptr;
|
main.c_config.term_reset_cmd = config_term_reset_cmd.ptr;
|
||||||
main.config.tty = ly_config.ly.tty;
|
main.c_config.tty = ly_config.ly.tty;
|
||||||
main.config.wayland_cmd = config_wayland_cmd.ptr;
|
main.c_config.wayland_cmd = config_wayland_cmd.ptr;
|
||||||
main.config.wayland_specifier = ly_config.ly.wayland_specifier;
|
main.c_config.wayland_specifier = ly_config.ly.wayland_specifier;
|
||||||
main.config.waylandsessions = config_waylandsessions.ptr;
|
main.c_config.waylandsessions = config_waylandsessions.ptr;
|
||||||
main.config.x_cmd = config_x_cmd.ptr;
|
main.c_config.x_cmd = config_x_cmd.ptr;
|
||||||
main.config.xinitrc = config_xinitrc.ptr;
|
main.c_config.xinitrc = config_xinitrc.ptr;
|
||||||
main.config.x_cmd_setup = config_x_cmd_setup.ptr;
|
main.c_config.x_cmd_setup = config_x_cmd_setup.ptr;
|
||||||
main.config.xauth_cmd = config_xauth_cmd.ptr;
|
main.c_config.xauth_cmd = config_xauth_cmd.ptr;
|
||||||
main.config.xsessions = config_xsessions.ptr;
|
main.c_config.xsessions = config_xsessions.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lang_load() !void {
|
pub fn lang_load() !void {
|
||||||
|
@ -243,6 +244,7 @@ pub fn lang_load() !void {
|
||||||
defer main.allocator.free(path);
|
defer main.allocator.free(path);
|
||||||
|
|
||||||
var file = try std.fs.cwd().openFile(path, .{});
|
var file = try std.fs.cwd().openFile(path, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
lang_buffer = try main.allocator.alloc(u8, INI_CONFIG_MAX_SIZE);
|
lang_buffer = try main.allocator.alloc(u8, INI_CONFIG_MAX_SIZE);
|
||||||
|
|
||||||
|
@ -296,119 +298,121 @@ pub fn lang_load() !void {
|
||||||
lang_wayland = try interop.c_str(ly_lang.ly.wayland);
|
lang_wayland = try interop.c_str(ly_lang.ly.wayland);
|
||||||
lang_xinitrc = try interop.c_str(ly_lang.ly.xinitrc);
|
lang_xinitrc = try interop.c_str(ly_lang.ly.xinitrc);
|
||||||
|
|
||||||
main.lang.capslock = lang_capslock.ptr;
|
main.c_lang.capslock = lang_capslock.ptr;
|
||||||
main.lang.err_alloc = lang_err_alloc.ptr;
|
main.c_lang.err_alloc = lang_err_alloc.ptr;
|
||||||
main.lang.err_bounds = lang_err_bounds.ptr;
|
main.c_lang.err_bounds = lang_err_bounds.ptr;
|
||||||
main.lang.err_chdir = lang_err_chdir.ptr;
|
main.c_lang.err_chdir = lang_err_chdir.ptr;
|
||||||
main.lang.err_console_dev = lang_err_console_dev.ptr;
|
main.c_lang.err_console_dev = lang_err_console_dev.ptr;
|
||||||
main.lang.err_dgn_oob = lang_err_dgn_oob.ptr;
|
main.c_lang.err_dgn_oob = lang_err_dgn_oob.ptr;
|
||||||
main.lang.err_domain = lang_err_domain.ptr;
|
main.c_lang.err_domain = lang_err_domain.ptr;
|
||||||
main.lang.err_hostname = lang_err_hostname.ptr;
|
main.c_lang.err_hostname = lang_err_hostname.ptr;
|
||||||
main.lang.err_mlock = lang_err_mlock.ptr;
|
main.c_lang.err_mlock = lang_err_mlock.ptr;
|
||||||
main.lang.err_null = lang_err_null.ptr;
|
main.c_lang.err_null = lang_err_null.ptr;
|
||||||
main.lang.err_pam = lang_err_pam.ptr;
|
main.c_lang.err_pam = lang_err_pam.ptr;
|
||||||
main.lang.err_pam_abort = lang_err_pam_abort.ptr;
|
main.c_lang.err_pam_abort = lang_err_pam_abort.ptr;
|
||||||
main.lang.err_pam_acct_expired = lang_err_pam_acct_expired.ptr;
|
main.c_lang.err_pam_acct_expired = lang_err_pam_acct_expired.ptr;
|
||||||
main.lang.err_pam_auth = lang_err_pam_auth.ptr;
|
main.c_lang.err_pam_auth = lang_err_pam_auth.ptr;
|
||||||
main.lang.err_pam_authinfo_unavail = lang_err_pam_authinfo_unavail.ptr;
|
main.c_lang.err_pam_authinfo_unavail = lang_err_pam_authinfo_unavail.ptr;
|
||||||
main.lang.err_pam_authok_reqd = lang_err_pam_authok_reqd.ptr;
|
main.c_lang.err_pam_authok_reqd = lang_err_pam_authok_reqd.ptr;
|
||||||
main.lang.err_pam_buf = lang_err_pam_buf.ptr;
|
main.c_lang.err_pam_buf = lang_err_pam_buf.ptr;
|
||||||
main.lang.err_pam_cred_err = lang_err_pam_cred_err.ptr;
|
main.c_lang.err_pam_cred_err = lang_err_pam_cred_err.ptr;
|
||||||
main.lang.err_pam_cred_expired = lang_err_pam_cred_expired.ptr;
|
main.c_lang.err_pam_cred_expired = lang_err_pam_cred_expired.ptr;
|
||||||
main.lang.err_pam_cred_insufficient = lang_err_pam_cred_insufficient.ptr;
|
main.c_lang.err_pam_cred_insufficient = lang_err_pam_cred_insufficient.ptr;
|
||||||
main.lang.err_pam_cred_unavail = lang_err_pam_cred_unavail.ptr;
|
main.c_lang.err_pam_cred_unavail = lang_err_pam_cred_unavail.ptr;
|
||||||
main.lang.err_pam_maxtries = lang_err_pam_maxtries.ptr;
|
main.c_lang.err_pam_maxtries = lang_err_pam_maxtries.ptr;
|
||||||
main.lang.err_pam_perm_denied = lang_err_pam_perm_denied.ptr;
|
main.c_lang.err_pam_perm_denied = lang_err_pam_perm_denied.ptr;
|
||||||
main.lang.err_pam_session = lang_err_pam_session.ptr;
|
main.c_lang.err_pam_session = lang_err_pam_session.ptr;
|
||||||
main.lang.err_pam_sys = lang_err_pam_sys.ptr;
|
main.c_lang.err_pam_sys = lang_err_pam_sys.ptr;
|
||||||
main.lang.err_pam_user_unknown = lang_err_pam_user_unknown.ptr;
|
main.c_lang.err_pam_user_unknown = lang_err_pam_user_unknown.ptr;
|
||||||
main.lang.err_path = lang_err_path.ptr;
|
main.c_lang.err_path = lang_err_path.ptr;
|
||||||
main.lang.err_perm_dir = lang_err_perm_dir.ptr;
|
main.c_lang.err_perm_dir = lang_err_perm_dir.ptr;
|
||||||
main.lang.err_perm_group = lang_err_perm_group.ptr;
|
main.c_lang.err_perm_group = lang_err_perm_group.ptr;
|
||||||
main.lang.err_perm_user = lang_err_perm_user.ptr;
|
main.c_lang.err_perm_user = lang_err_perm_user.ptr;
|
||||||
main.lang.err_pwnam = lang_err_pwnam.ptr;
|
main.c_lang.err_pwnam = lang_err_pwnam.ptr;
|
||||||
main.lang.err_user_gid = lang_err_user_gid.ptr;
|
main.c_lang.err_user_gid = lang_err_user_gid.ptr;
|
||||||
main.lang.err_user_init = lang_err_user_init.ptr;
|
main.c_lang.err_user_init = lang_err_user_init.ptr;
|
||||||
main.lang.err_user_uid = lang_err_user_uid.ptr;
|
main.c_lang.err_user_uid = lang_err_user_uid.ptr;
|
||||||
main.lang.err_xsessions_dir = lang_err_xsessions_dir.ptr;
|
main.c_lang.err_xsessions_dir = lang_err_xsessions_dir.ptr;
|
||||||
main.lang.err_xsessions_open = lang_err_xsessions_open.ptr;
|
main.c_lang.err_xsessions_open = lang_err_xsessions_open.ptr;
|
||||||
main.lang.f1 = lang_f1.ptr;
|
main.c_lang.f1 = lang_f1.ptr;
|
||||||
main.lang.f2 = lang_f2.ptr;
|
main.c_lang.f2 = lang_f2.ptr;
|
||||||
main.lang.login = lang_login.ptr;
|
main.c_lang.login = lang_login.ptr;
|
||||||
main.lang.logout = lang_logout.ptr;
|
main.c_lang.logout = lang_logout.ptr;
|
||||||
main.lang.numlock = lang_numlock.ptr;
|
main.c_lang.numlock = lang_numlock.ptr;
|
||||||
main.lang.password = lang_password.ptr;
|
main.c_lang.password = lang_password.ptr;
|
||||||
main.lang.shell = lang_shell.ptr;
|
main.c_lang.shell = lang_shell.ptr;
|
||||||
main.lang.wayland = lang_wayland.ptr;
|
main.c_lang.wayland = lang_wayland.ptr;
|
||||||
main.lang.xinitrc = lang_xinitrc.ptr;
|
main.c_lang.xinitrc = lang_xinitrc.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn config_free() void {
|
pub fn config_free() void {
|
||||||
main.allocator.free(config_clock);
|
interop.allocator.free(config_clock);
|
||||||
main.allocator.free(config_console_dev);
|
interop.allocator.free(config_console_dev);
|
||||||
main.allocator.free(config_lang);
|
interop.allocator.free(config_lang);
|
||||||
main.allocator.free(config_mcookie_cmd);
|
interop.allocator.free(config_mcookie_cmd);
|
||||||
main.allocator.free(config_path);
|
interop.allocator.free(config_path);
|
||||||
main.allocator.free(config_restart_cmd);
|
interop.allocator.free(config_restart_cmd);
|
||||||
main.allocator.free(config_save_file);
|
interop.allocator.free(config_save_file);
|
||||||
main.allocator.free(config_service_name);
|
interop.allocator.free(config_service_name);
|
||||||
main.allocator.free(config_shutdown_cmd);
|
interop.allocator.free(config_shutdown_cmd);
|
||||||
main.allocator.free(config_term_reset_cmd);
|
interop.allocator.free(config_term_reset_cmd);
|
||||||
main.allocator.free(config_wayland_cmd);
|
interop.allocator.free(config_wayland_cmd);
|
||||||
main.allocator.free(config_waylandsessions);
|
interop.allocator.free(config_waylandsessions);
|
||||||
main.allocator.free(config_x_cmd);
|
interop.allocator.free(config_x_cmd);
|
||||||
main.allocator.free(config_xinitrc);
|
interop.allocator.free(config_xinitrc);
|
||||||
main.allocator.free(config_x_cmd_setup);
|
interop.allocator.free(config_x_cmd_setup);
|
||||||
main.allocator.free(config_xauth_cmd);
|
interop.allocator.free(config_xauth_cmd);
|
||||||
main.allocator.free(config_xsessions);
|
interop.allocator.free(config_xsessions);
|
||||||
|
|
||||||
main.allocator.free(config_buffer);
|
main.allocator.free(config_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lang_free() void {
|
pub fn lang_free() void {
|
||||||
main.allocator.free(lang_capslock);
|
interop.allocator.free(lang_capslock);
|
||||||
main.allocator.free(lang_err_alloc);
|
interop.allocator.free(lang_err_alloc);
|
||||||
main.allocator.free(lang_err_bounds);
|
interop.allocator.free(lang_err_bounds);
|
||||||
main.allocator.free(lang_err_chdir);
|
interop.allocator.free(lang_err_chdir);
|
||||||
main.allocator.free(lang_err_console_dev);
|
interop.allocator.free(lang_err_console_dev);
|
||||||
main.allocator.free(lang_err_dgn_oob);
|
interop.allocator.free(lang_err_dgn_oob);
|
||||||
main.allocator.free(lang_err_domain);
|
interop.allocator.free(lang_err_domain);
|
||||||
main.allocator.free(lang_err_hostname);
|
interop.allocator.free(lang_err_hostname);
|
||||||
main.allocator.free(lang_err_mlock);
|
interop.allocator.free(lang_err_mlock);
|
||||||
main.allocator.free(lang_err_null);
|
interop.allocator.free(lang_err_null);
|
||||||
main.allocator.free(lang_err_pam);
|
interop.allocator.free(lang_err_pam);
|
||||||
main.allocator.free(lang_err_pam_abort);
|
interop.allocator.free(lang_err_pam_abort);
|
||||||
main.allocator.free(lang_err_pam_acct_expired);
|
interop.allocator.free(lang_err_pam_acct_expired);
|
||||||
main.allocator.free(lang_err_pam_auth);
|
interop.allocator.free(lang_err_pam_auth);
|
||||||
main.allocator.free(lang_err_pam_authinfo_unavail);
|
interop.allocator.free(lang_err_pam_authinfo_unavail);
|
||||||
main.allocator.free(lang_err_pam_authok_reqd);
|
interop.allocator.free(lang_err_pam_authok_reqd);
|
||||||
main.allocator.free(lang_err_pam_buf);
|
interop.allocator.free(lang_err_pam_buf);
|
||||||
main.allocator.free(lang_err_pam_cred_err);
|
interop.allocator.free(lang_err_pam_cred_err);
|
||||||
main.allocator.free(lang_err_pam_cred_expired);
|
interop.allocator.free(lang_err_pam_cred_expired);
|
||||||
main.allocator.free(lang_err_pam_cred_insufficient);
|
interop.allocator.free(lang_err_pam_cred_insufficient);
|
||||||
main.allocator.free(lang_err_pam_cred_unavail);
|
interop.allocator.free(lang_err_pam_cred_unavail);
|
||||||
main.allocator.free(lang_err_pam_maxtries);
|
interop.allocator.free(lang_err_pam_maxtries);
|
||||||
main.allocator.free(lang_err_pam_perm_denied);
|
interop.allocator.free(lang_err_pam_perm_denied);
|
||||||
main.allocator.free(lang_err_pam_session);
|
interop.allocator.free(lang_err_pam_session);
|
||||||
main.allocator.free(lang_err_pam_sys);
|
interop.allocator.free(lang_err_pam_sys);
|
||||||
main.allocator.free(lang_err_pam_user_unknown);
|
interop.allocator.free(lang_err_pam_user_unknown);
|
||||||
main.allocator.free(lang_err_path);
|
interop.allocator.free(lang_err_path);
|
||||||
main.allocator.free(lang_err_perm_dir);
|
interop.allocator.free(lang_err_perm_dir);
|
||||||
main.allocator.free(lang_err_perm_group);
|
interop.allocator.free(lang_err_perm_group);
|
||||||
main.allocator.free(lang_err_perm_user);
|
interop.allocator.free(lang_err_perm_user);
|
||||||
main.allocator.free(lang_err_pwnam);
|
interop.allocator.free(lang_err_pwnam);
|
||||||
main.allocator.free(lang_err_user_gid);
|
interop.allocator.free(lang_err_user_gid);
|
||||||
main.allocator.free(lang_err_user_init);
|
interop.allocator.free(lang_err_user_init);
|
||||||
main.allocator.free(lang_err_user_uid);
|
interop.allocator.free(lang_err_user_uid);
|
||||||
main.allocator.free(lang_err_xsessions_dir);
|
interop.allocator.free(lang_err_xsessions_dir);
|
||||||
main.allocator.free(lang_err_xsessions_open);
|
interop.allocator.free(lang_err_xsessions_open);
|
||||||
main.allocator.free(lang_f1);
|
interop.allocator.free(lang_f1);
|
||||||
main.allocator.free(lang_f2);
|
interop.allocator.free(lang_f2);
|
||||||
main.allocator.free(lang_login);
|
interop.allocator.free(lang_login);
|
||||||
main.allocator.free(lang_logout);
|
interop.allocator.free(lang_logout);
|
||||||
main.allocator.free(lang_numlock);
|
interop.allocator.free(lang_numlock);
|
||||||
main.allocator.free(lang_password);
|
interop.allocator.free(lang_password);
|
||||||
main.allocator.free(lang_shell);
|
interop.allocator.free(lang_shell);
|
||||||
main.allocator.free(lang_wayland);
|
interop.allocator.free(lang_wayland);
|
||||||
main.allocator.free(lang_xinitrc);
|
interop.allocator.free(lang_xinitrc);
|
||||||
|
|
||||||
main.allocator.free(lang_buffer);
|
main.allocator.free(lang_buffer);
|
||||||
}
|
}
|
||||||
|
|
155
src/ini.zig
155
src/ini.zig
|
@ -1,116 +1,92 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
// we ignore whitespace and comments
|
|
||||||
pub const Token = union(enum) { comment, section: []const u8, key: []const u8, value: []const u8 };
|
pub const Token = union(enum) { comment, section: []const u8, key: []const u8, value: []const u8 };
|
||||||
|
|
||||||
pub const State = enum { normal, section, key, value, comment };
|
pub fn getTok(data: []const u8, pos: *usize) ?Token {
|
||||||
|
// If the position advances to the end of the data, there's no more tokens for us
|
||||||
pub fn getTok(data: []const u8, pos: *usize, state: *State) ?Token {
|
if (pos.* >= data.len) {
|
||||||
// if the position advances to the end of the data, there's no more tokens for us
|
return null;
|
||||||
if (pos.* >= data.len) return null;
|
}
|
||||||
var cur: u8 = 0;
|
|
||||||
// used for slicing
|
|
||||||
var start = pos.*;
|
|
||||||
var end = start;
|
|
||||||
|
|
||||||
while (pos.* < data.len) {
|
while (pos.* < data.len) {
|
||||||
cur = data[pos.*];
|
var current = data[pos.*];
|
||||||
pos.* += 1;
|
pos.* += 1;
|
||||||
switch (state.*) {
|
|
||||||
.normal => {
|
switch (current) {
|
||||||
switch (cur) {
|
' ', '\t', '\r', '\n' => {},
|
||||||
'[' => {
|
'[' => {
|
||||||
state.* = .section;
|
var start = pos.*;
|
||||||
start = pos.*;
|
|
||||||
end = start;
|
current = data[pos.*];
|
||||||
},
|
|
||||||
'=' => {
|
while (current != ']') : (pos.* += 1) {
|
||||||
state.* = .value;
|
current = data[pos.*];
|
||||||
start = pos.*;
|
|
||||||
if (std.ascii.isWhitespace(data[start])) start += 1;
|
|
||||||
end = start;
|
|
||||||
},
|
|
||||||
';', '#' => {
|
|
||||||
state.* = .comment;
|
|
||||||
},
|
|
||||||
// if it is whitespace itgets skipped over anyways
|
|
||||||
else => if (!std.ascii.isWhitespace(cur)) {
|
|
||||||
state.* = .key;
|
|
||||||
start = pos.* - 1;
|
|
||||||
end = start;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Token{ .section = data[start .. pos.* - 1] };
|
||||||
},
|
},
|
||||||
.section => {
|
'=' => {
|
||||||
end += 1;
|
current = data[pos.*];
|
||||||
switch (cur) {
|
|
||||||
']' => {
|
while (current == ' ' or current == '\t') {
|
||||||
state.* = .normal;
|
pos.* += 1;
|
||||||
pos.* += 1;
|
current = data[pos.*];
|
||||||
return Token{ .section = data[start .. end - 1] };
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var start = pos.*;
|
||||||
|
|
||||||
|
while (current != '\n') : (pos.* += 1) {
|
||||||
|
current = data[pos.*];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Token{ .value = if (start == pos.*) "" else data[start .. pos.* - 1] };
|
||||||
},
|
},
|
||||||
.value => {
|
';', '#' => {
|
||||||
switch (cur) {
|
current = data[pos.*];
|
||||||
';', '#' => {
|
|
||||||
state.* = .comment;
|
while (current != '\n') : (pos.* += 1) {
|
||||||
return Token{ .value = data[start .. end - 2] };
|
current = data[pos.*];
|
||||||
},
|
|
||||||
else => {
|
|
||||||
end += 1;
|
|
||||||
switch (cur) {
|
|
||||||
'\n' => {
|
|
||||||
state.* = .normal;
|
|
||||||
return Token{ .value = data[start .. end - 2] };
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Token.comment;
|
||||||
},
|
},
|
||||||
.comment => {
|
else => {
|
||||||
end += 1;
|
var start = pos.* - 1;
|
||||||
switch (cur) {
|
|
||||||
'\n' => {
|
current = data[pos.*];
|
||||||
state.* = .normal;
|
|
||||||
return Token.comment;
|
while (std.ascii.isAlphanumeric(current) or current == '_') : (pos.* += 1) {
|
||||||
},
|
current = data[pos.*];
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.key => {
|
|
||||||
end += 1;
|
|
||||||
if (!(std.ascii.isAlphanumeric(cur) or cur == '_')) {
|
|
||||||
state.* = .normal;
|
|
||||||
return Token{ .key = data[start..end] };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos.* -= 1;
|
||||||
|
|
||||||
|
return Token{ .key = data[start..pos.*] };
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
pub fn readToStruct(comptime T: type, data: []const u8) !T {
|
pub fn readToStruct(comptime T: type, data: []const u8) !T {
|
||||||
var namespace: []const u8 = "";
|
var namespace: []const u8 = "";
|
||||||
var pos: usize = 0;
|
var pos: usize = 0;
|
||||||
var state: State = .normal;
|
|
||||||
var ret = std.mem.zeroes(T);
|
var ret = std.mem.zeroes(T);
|
||||||
while (getTok(data, &pos, &state)) |tok| {
|
while (getTok(data, &pos)) |tok| {
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
.comment => {},
|
.comment => {},
|
||||||
.section => |ns| {
|
.section => |ns| {
|
||||||
namespace = ns;
|
namespace = ns;
|
||||||
},
|
},
|
||||||
.key => |key| {
|
.key => |key| {
|
||||||
var next_tok = getTok(data, &pos, &state);
|
var next_tok = getTok(data, &pos);
|
||||||
// if there's nothing just give a comment which is also a syntax error
|
// if there's nothing just give a comment which is also a syntax error
|
||||||
switch (next_tok orelse .comment) {
|
switch (next_tok orelse .comment) {
|
||||||
.value => |value| {
|
.value => |value| {
|
||||||
// now we have the namespace, key, and value
|
// now we have the namespace, key, and value
|
||||||
// namespace and key are runtime values, so we need to loop the struct instead of using @field
|
// namespace and key are runtime values, so we need to loop the struct instead of using @field
|
||||||
inline for (std.meta.fields(T)) |ns_info| {
|
inline for (std.meta.fields(T)) |ns_info| {
|
||||||
if (std.mem.eql(u8, ns_info.name, namespace)) {
|
if (eql(ns_info.name, namespace)) {
|
||||||
// @field(ret, ns_info.name) contains the inner struct now
|
// @field(ret, ns_info.name) contains the inner struct now
|
||||||
// loop over the fields of the inner struct, and check for key matches
|
// loop over the fields of the inner struct, and check for key matches
|
||||||
inline for (std.meta.fields(@TypeOf(@field(ret, ns_info.name)))) |key_info| {
|
inline for (std.meta.fields(@TypeOf(@field(ret, ns_info.name)))) |key_info| {
|
||||||
|
@ -124,11 +100,11 @@ pub fn readToStruct(comptime T: type, data: []const u8) !T {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// after a key, a value must follow
|
// after a key, a value must follow
|
||||||
else => return error.SyntaxError,
|
else => return error.NoValueAfterKey,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// if we get a value with no key, that's a bit nonsense
|
// if we get a value with no key, that's a bit nonsense
|
||||||
.value => return error.SyntaxError,
|
.value => return error.ValueWithNoKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -171,6 +147,7 @@ pub fn writeStruct(struct_value: anytype, writer: anytype) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Checks if the string is actually a single ASCII character, else, parse as an integer
|
||||||
fn parseInt(comptime T: type, buf: []const u8, base: u8) std.fmt.ParseIntError!T {
|
fn parseInt(comptime T: type, buf: []const u8, base: u8) std.fmt.ParseIntError!T {
|
||||||
if (buf.len == 1) {
|
if (buf.len == 1) {
|
||||||
var first_char = buf[0];
|
var first_char = buf[0];
|
||||||
|
@ -182,3 +159,21 @@ fn parseInt(comptime T: type, buf: []const u8, base: u8) std.fmt.ParseIntError!T
|
||||||
|
|
||||||
return std.fmt.parseInt(T, buf, base);
|
return std.fmt.parseInt(T, buf, base);
|
||||||
}
|
}
|
||||||
|
// Checks if 2 strings are equal, but comparing " " with "_"
|
||||||
|
fn eql(a: []const u8, b: []const u8) bool {
|
||||||
|
if (a.len != b.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.ptr == b.ptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (a, b) |a_elem, b_elem| {
|
||||||
|
if (a_elem != if (b_elem == ' ') '_' else b_elem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
const main = @import("main.zig");
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const allocator = std.heap.raw_c_allocator;
|
||||||
|
|
||||||
pub fn c_str(str: []const u8) ![:0]u8 {
|
pub fn c_str(str: []const u8) ![:0]u8 {
|
||||||
const new_str = try main.allocator.allocSentinel(u8, str.len, 0);
|
const new_str = try allocator.allocSentinel(u8, str.len, 0);
|
||||||
|
|
||||||
for (str, 0..) |c, i| {
|
for (str, 0..) |c, i| {
|
||||||
new_str[i] = c;
|
new_str[i] = c;
|
||||||
|
|
103
src/main.zig
103
src/main.zig
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const configuration = @import("config.zig");
|
const config = @import("config.zig");
|
||||||
|
const utils = @import("utils.zig");
|
||||||
|
|
||||||
pub const c = @cImport({
|
pub const c = @cImport({
|
||||||
@cInclude("dragonfail.h");
|
@cInclude("dragonfail.h");
|
||||||
|
@ -22,12 +23,12 @@ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
pub const allocator = gpa.allocator();
|
pub const allocator = gpa.allocator();
|
||||||
|
|
||||||
// Ly general and language configuration
|
// Ly general and language configuration
|
||||||
pub var config: c.struct_config = undefined;
|
pub var c_config: c.struct_config = undefined;
|
||||||
pub var lang: c.struct_lang = undefined;
|
pub var c_lang: c.struct_lang = undefined;
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
@export(config, .{ .name = "config" });
|
@export(c_config, .{ .name = "config" });
|
||||||
@export(lang, .{ .name = "lang" });
|
@export(c_lang, .{ .name = "lang" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main function
|
// Main function
|
||||||
|
@ -39,8 +40,8 @@ pub fn main() !void {
|
||||||
var lang_ptr = try allocator.create(c.struct_lang);
|
var lang_ptr = try allocator.create(c.struct_lang);
|
||||||
defer allocator.destroy(lang_ptr);
|
defer allocator.destroy(lang_ptr);
|
||||||
|
|
||||||
config = config_ptr.*;
|
c_config = config_ptr.*;
|
||||||
lang = lang_ptr.*;
|
c_lang = lang_ptr.*;
|
||||||
|
|
||||||
// Initialize error library
|
// Initialize error library
|
||||||
log_init(c.dgn_init());
|
log_init(c.dgn_init());
|
||||||
|
@ -78,12 +79,12 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load configuration and language
|
// Load configuration and language
|
||||||
try configuration.config_load(config_path);
|
try config.config_load(config_path);
|
||||||
try configuration.lang_load();
|
try config.lang_load();
|
||||||
|
|
||||||
if (c.dgn_catch() != 0) {
|
if (c.dgn_catch() != 0) {
|
||||||
configuration.config_free();
|
config.config_free();
|
||||||
configuration.lang_free();
|
config.lang_free();
|
||||||
std.os.exit(1);
|
std.os.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,11 +99,11 @@ pub fn main() !void {
|
||||||
defer allocator.destroy(password);
|
defer allocator.destroy(password);
|
||||||
|
|
||||||
c.input_desktop(desktop);
|
c.input_desktop(desktop);
|
||||||
c.input_text(username, config.max_login_len);
|
c.input_text(username, config.ly_config.ly.max_login_len);
|
||||||
c.input_text(password, config.max_password_len);
|
c.input_text(password, config.ly_config.ly.max_password_len);
|
||||||
|
|
||||||
c.desktop_load(desktop);
|
utils.desktop_load(desktop);
|
||||||
c.load(desktop, username);
|
try utils.load(desktop, username);
|
||||||
|
|
||||||
// Start termbox
|
// Start termbox
|
||||||
_ = c.tb_init();
|
_ = c.tb_init();
|
||||||
|
@ -119,10 +120,10 @@ pub fn main() !void {
|
||||||
// Place the cursor on the login field if there is no saved username
|
// Place the cursor on the login field if there is no saved username
|
||||||
// If there is, place the curser on the password field
|
// If there is, place the curser on the password field
|
||||||
var active_input: u8 = 0;
|
var active_input: u8 = 0;
|
||||||
if (config.default_input == c.LOGIN_INPUT and username.text != username.end) {
|
if (config.ly_config.ly.default_input == c.LOGIN_INPUT and username.text != username.end) {
|
||||||
active_input = c.PASSWORD_INPUT;
|
active_input = c.PASSWORD_INPUT;
|
||||||
} else {
|
} else {
|
||||||
active_input = config.default_input;
|
active_input = config.ly_config.ly.default_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize drawing code
|
// Initialize drawing code
|
||||||
|
@ -146,11 +147,11 @@ pub fn main() !void {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.animate) {
|
if (config.ly_config.ly.animate) {
|
||||||
c.animate_init(buffer);
|
c.animate_init(buffer);
|
||||||
|
|
||||||
if (c.dgn_catch() != 0) {
|
if (c.dgn_catch() != 0) {
|
||||||
config.animate = false;
|
config.ly_config.ly.animate = false;
|
||||||
c.dgn_reset();
|
c.dgn_reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +189,7 @@ pub fn main() !void {
|
||||||
c.draw_box(buffer);
|
c.draw_box(buffer);
|
||||||
c.draw_clock(buffer);
|
c.draw_clock(buffer);
|
||||||
c.draw_labels(buffer);
|
c.draw_labels(buffer);
|
||||||
if (!config.hide_f1_commands) {
|
if (!config.ly_config.ly.hide_f1_commands) {
|
||||||
c.draw_f_commands();
|
c.draw_f_commands();
|
||||||
}
|
}
|
||||||
c.draw_lock_state(buffer);
|
c.draw_lock_state(buffer);
|
||||||
|
@ -196,7 +197,7 @@ pub fn main() !void {
|
||||||
c.draw_desktop(desktop);
|
c.draw_desktop(desktop);
|
||||||
c.draw_input(username);
|
c.draw_input(username);
|
||||||
c.draw_input_mask(password);
|
c.draw_input_mask(password);
|
||||||
update = config.animate;
|
update = config.ly_config.ly.animate;
|
||||||
} else {
|
} else {
|
||||||
std.time.sleep(10000000); // Sleep 0.01 seconds
|
std.time.sleep(10000000); // Sleep 0.01 seconds
|
||||||
update = c.cascade(buffer, &auth_fails);
|
update = c.cascade(buffer, &auth_fails);
|
||||||
|
@ -207,8 +208,8 @@ pub fn main() !void {
|
||||||
|
|
||||||
var timeout: c_int = -1;
|
var timeout: c_int = -1;
|
||||||
|
|
||||||
if (config.animate) {
|
if (config.ly_config.ly.animate) {
|
||||||
timeout = config.min_refresh_delta;
|
timeout = config.ly_config.ly.min_refresh_delta;
|
||||||
} else {
|
} else {
|
||||||
// TODO: Use the Zig standard library directly
|
// TODO: Use the Zig standard library directly
|
||||||
var time = try allocator.create(std.os.linux.timeval);
|
var time = try allocator.create(std.os.linux.timeval);
|
||||||
|
@ -216,9 +217,9 @@ pub fn main() !void {
|
||||||
|
|
||||||
_ = std.os.linux.gettimeofday(time, undefined);
|
_ = std.os.linux.gettimeofday(time, undefined);
|
||||||
|
|
||||||
if (config.bigclock) {
|
if (config.ly_config.ly.bigclock) {
|
||||||
timeout = @intCast(c_int, (60 - @mod(time.tv_sec, 60)) * 1000 - @divTrunc(time.tv_usec, 1000) + 1);
|
timeout = @intCast(c_int, (60 - @mod(time.tv_sec, 60)) * 1000 - @divTrunc(time.tv_usec, 1000) + 1);
|
||||||
} else if (config.clock != undefined) {
|
} else if (config.ly_config.ly.clock.len > 0) {
|
||||||
timeout = @intCast(c_int, 1000 - @divTrunc(time.tv_usec, 1000) + 1);
|
timeout = @intCast(c_int, 1000 - @divTrunc(time.tv_usec, 1000) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +284,7 @@ pub fn main() !void {
|
||||||
update = true;
|
update = true;
|
||||||
},
|
},
|
||||||
c.TB_KEY_ENTER => {
|
c.TB_KEY_ENTER => {
|
||||||
c.save(desktop, username);
|
try utils.save(desktop, username);
|
||||||
c.auth(desktop, username, password, buffer);
|
c.auth(desktop, username, password, buffer);
|
||||||
|
|
||||||
if (c.dgn_catch() != 0) {
|
if (c.dgn_catch() != 0) {
|
||||||
|
@ -296,16 +297,16 @@ pub fn main() !void {
|
||||||
buffer.info_line = c.dgn_output_log();
|
buffer.info_line = c.dgn_output_log();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.blank_password) {
|
if (config.ly_config.ly.blank_password) {
|
||||||
c.input_text_clear(password);
|
c.input_text_clear(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
c.dgn_reset();
|
c.dgn_reset();
|
||||||
} else {
|
} else {
|
||||||
buffer.info_line = lang.logout;
|
buffer.info_line = c_lang.logout;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.load(desktop, username);
|
try utils.load(desktop, username);
|
||||||
|
|
||||||
// Reset cursor to its normal state
|
// Reset cursor to its normal state
|
||||||
_ = std.ChildProcess.exec(.{ .argv = &[_][]const u8{ "/usr/bin/tput", "cnorm" }, .allocator = allocator }) catch return;
|
_ = std.ChildProcess.exec(.{ .argv = &[_][]const u8{ "/usr/bin/tput", "cnorm" }, .allocator = allocator }) catch return;
|
||||||
|
@ -330,45 +331,45 @@ pub fn main() !void {
|
||||||
|
|
||||||
// Unload configuration
|
// Unload configuration
|
||||||
c.draw_free(buffer);
|
c.draw_free(buffer);
|
||||||
configuration.lang_free();
|
config.lang_free();
|
||||||
|
|
||||||
if (shutdown) {
|
if (shutdown) {
|
||||||
var shutdown_cmd = try std.fmt.allocPrint(allocator, "{s}", .{config.shutdown_cmd});
|
var shutdown_cmd = try std.fmt.allocPrint(allocator, "{s}", .{config.ly_config.ly.shutdown_cmd});
|
||||||
// This will never be freed! But it's fine, we're shutting down the system anyway
|
// This will never be freed! But it's fine, we're shutting down the system anyway
|
||||||
defer allocator.free(shutdown_cmd);
|
defer allocator.free(shutdown_cmd);
|
||||||
|
|
||||||
configuration.config_free();
|
config.config_free();
|
||||||
|
|
||||||
std.process.execv(allocator, &[_][]const u8{ "/bin/sh", "-c", shutdown_cmd }) catch return;
|
std.process.execv(allocator, &[_][]const u8{ "/bin/sh", "-c", shutdown_cmd }) catch return;
|
||||||
} else if (reboot) {
|
} else if (reboot) {
|
||||||
var restart_cmd = try std.fmt.allocPrint(allocator, "{s}", .{config.restart_cmd});
|
var restart_cmd = try std.fmt.allocPrint(allocator, "{s}", .{config.ly_config.ly.restart_cmd});
|
||||||
// This will never be freed! But it's fine, we're rebooting the system anyway
|
// This will never be freed! But it's fine, we're rebooting the system anyway
|
||||||
defer allocator.free(restart_cmd);
|
defer allocator.free(restart_cmd);
|
||||||
|
|
||||||
configuration.config_free();
|
config.config_free();
|
||||||
|
|
||||||
std.process.execv(allocator, &[_][]const u8{ "/bin/sh", "-c", restart_cmd }) catch return;
|
std.process.execv(allocator, &[_][]const u8{ "/bin/sh", "-c", restart_cmd }) catch return;
|
||||||
} else {
|
} else {
|
||||||
configuration.config_free();
|
config.config_free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Low-level error messages
|
// Low-level error messages
|
||||||
fn log_init(log: [*c][*c]u8) void {
|
fn log_init(log: [*c][*c]u8) void {
|
||||||
log[c.DGN_OK] = lang.err_dgn_oob;
|
log[c.DGN_OK] = c_lang.err_dgn_oob;
|
||||||
log[c.DGN_NULL] = lang.err_null;
|
log[c.DGN_NULL] = c_lang.err_null;
|
||||||
log[c.DGN_ALLOC] = lang.err_alloc;
|
log[c.DGN_ALLOC] = c_lang.err_alloc;
|
||||||
log[c.DGN_BOUNDS] = lang.err_bounds;
|
log[c.DGN_BOUNDS] = c_lang.err_bounds;
|
||||||
log[c.DGN_DOMAIN] = lang.err_domain;
|
log[c.DGN_DOMAIN] = c_lang.err_domain;
|
||||||
log[c.DGN_MLOCK] = lang.err_mlock;
|
log[c.DGN_MLOCK] = c_lang.err_mlock;
|
||||||
log[c.DGN_XSESSIONS_DIR] = lang.err_xsessions_dir;
|
log[c.DGN_XSESSIONS_DIR] = c_lang.err_xsessions_dir;
|
||||||
log[c.DGN_XSESSIONS_OPEN] = lang.err_xsessions_open;
|
log[c.DGN_XSESSIONS_OPEN] = c_lang.err_xsessions_open;
|
||||||
log[c.DGN_PATH] = lang.err_path;
|
log[c.DGN_PATH] = c_lang.err_path;
|
||||||
log[c.DGN_CHDIR] = lang.err_chdir;
|
log[c.DGN_CHDIR] = c_lang.err_chdir;
|
||||||
log[c.DGN_PWNAM] = lang.err_pwnam;
|
log[c.DGN_PWNAM] = c_lang.err_pwnam;
|
||||||
log[c.DGN_USER_INIT] = lang.err_user_init;
|
log[c.DGN_USER_INIT] = c_lang.err_user_init;
|
||||||
log[c.DGN_USER_GID] = lang.err_user_gid;
|
log[c.DGN_USER_GID] = c_lang.err_user_gid;
|
||||||
log[c.DGN_USER_UID] = lang.err_user_uid;
|
log[c.DGN_USER_UID] = c_lang.err_user_uid;
|
||||||
log[c.DGN_PAM] = lang.err_pam;
|
log[c.DGN_PAM] = c_lang.err_pam;
|
||||||
log[c.DGN_HOSTNAME] = lang.err_hostname;
|
log[c.DGN_HOSTNAME] = c_lang.err_hostname;
|
||||||
}
|
}
|
||||||
|
|
208
src/utils.c
208
src/utils.c
|
@ -19,142 +19,6 @@
|
||||||
#include <linux/vt.h>
|
#include <linux/vt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void config_handle_str(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
if (*((char**)data) != NULL)
|
|
||||||
{
|
|
||||||
free(*((char**)data));
|
|
||||||
}
|
|
||||||
|
|
||||||
*((char**)data) = strdup(*pars);
|
|
||||||
}
|
|
||||||
|
|
||||||
void desktop_crawl(
|
|
||||||
struct desktop* target,
|
|
||||||
char* sessions,
|
|
||||||
enum display_server server)
|
|
||||||
{
|
|
||||||
DIR* dir;
|
|
||||||
struct dirent* dir_info;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
ok = access(sessions, F_OK);
|
|
||||||
|
|
||||||
if (ok == -1)
|
|
||||||
{
|
|
||||||
dgn_throw(DGN_XSESSIONS_DIR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dir = opendir(sessions);
|
|
||||||
|
|
||||||
if (dir == NULL)
|
|
||||||
{
|
|
||||||
dgn_throw(DGN_XSESSIONS_OPEN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* name = NULL;
|
|
||||||
char* exec = NULL;
|
|
||||||
|
|
||||||
struct configator_param map_desktop[] =
|
|
||||||
{
|
|
||||||
{"Exec", &exec, config_handle_str},
|
|
||||||
{"Name", &name, config_handle_str},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct configator_param* map[] =
|
|
||||||
{
|
|
||||||
NULL,
|
|
||||||
map_desktop,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct configator_param sections[] =
|
|
||||||
{
|
|
||||||
{"Desktop Entry", NULL, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t map_len[] = {0, 2};
|
|
||||||
uint16_t sections_len = 1;
|
|
||||||
|
|
||||||
struct configator desktop_config;
|
|
||||||
desktop_config.map = map;
|
|
||||||
desktop_config.map_len = map_len;
|
|
||||||
desktop_config.sections = sections;
|
|
||||||
desktop_config.sections_len = sections_len;
|
|
||||||
|
|
||||||
#if defined(NAME_MAX)
|
|
||||||
char path[NAME_MAX];
|
|
||||||
#elif defined(_POSIX_PATH_MAX)
|
|
||||||
char path[_POSIX_PATH_MAX];
|
|
||||||
#else
|
|
||||||
char path[1024];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dir_info = readdir(dir);
|
|
||||||
|
|
||||||
while (dir_info != NULL)
|
|
||||||
{
|
|
||||||
if ((dir_info->d_name)[0] == '.')
|
|
||||||
{
|
|
||||||
dir_info = readdir(dir);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(path, (sizeof (path)) - 1, "%s/", sessions);
|
|
||||||
strncat(path, dir_info->d_name, (sizeof (path)) - 1);
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
input_desktop_add(target, name, exec, server);
|
|
||||||
}
|
|
||||||
|
|
||||||
name = NULL;
|
|
||||||
exec = NULL;
|
|
||||||
dir_info = readdir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
void desktop_load(struct desktop* target)
|
|
||||||
{
|
|
||||||
// we don't care about desktop environments presence
|
|
||||||
// because the fallback shell is always available
|
|
||||||
// so we just dismiss any "throw" for now
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
desktop_crawl(target, config.waylandsessions, DS_WAYLAND);
|
|
||||||
|
|
||||||
if (dgn_catch())
|
|
||||||
{
|
|
||||||
++err;
|
|
||||||
dgn_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
desktop_crawl(target, config.xsessions, DS_XORG);
|
|
||||||
|
|
||||||
if (dgn_catch())
|
|
||||||
{
|
|
||||||
++err;
|
|
||||||
dgn_reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* hostname_backup = NULL;
|
static char* hostname_backup = NULL;
|
||||||
|
|
||||||
void hostname(char** out)
|
void hostname(char** out)
|
||||||
|
@ -211,76 +75,4 @@ void switch_tty(struct term_buf* buf)
|
||||||
ioctl(fd, VT_WAITACTIVE, config.tty);
|
ioctl(fd, VT_WAITACTIVE, config.tty);
|
||||||
|
|
||||||
fclose(console);
|
fclose(console);
|
||||||
}
|
|
||||||
|
|
||||||
void save(struct desktop* desktop, struct text* login)
|
|
||||||
{
|
|
||||||
if (config.save)
|
|
||||||
{
|
|
||||||
FILE* fp = fopen(config.save_file, "wb+");
|
|
||||||
|
|
||||||
if (fp != NULL)
|
|
||||||
{
|
|
||||||
fprintf(fp, "%s\n%d", login->text, desktop->cur);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void load(struct desktop* desktop, struct text* login)
|
|
||||||
{
|
|
||||||
if (!config.load)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* fp = fopen(config.save_file, "rb");
|
|
||||||
|
|
||||||
if (fp == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* line = malloc(config.max_login_len + 1);
|
|
||||||
|
|
||||||
if (line == NULL)
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fgets(line, config.max_login_len + 1, fp))
|
|
||||||
{
|
|
||||||
int len = strlen(line);
|
|
||||||
strncpy(login->text, line, login->len);
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
login->end = login->text;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
login->end = login->text + len - 1;
|
|
||||||
login->text[len - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
free(line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fgets(line, config.max_login_len + 1, fp))
|
|
||||||
{
|
|
||||||
int saved_cur = abs(atoi(line));
|
|
||||||
|
|
||||||
if (saved_cur < desktop->len)
|
|
||||||
{
|
|
||||||
desktop->cur = saved_cur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
free(line);
|
|
||||||
}
|
}
|
|
@ -9,7 +9,5 @@ void desktop_load(struct desktop* target);
|
||||||
void hostname(char** out);
|
void hostname(char** out);
|
||||||
void free_hostname();
|
void free_hostname();
|
||||||
void switch_tty(struct term_buf* buf);
|
void switch_tty(struct term_buf* buf);
|
||||||
void save(struct desktop* desktop, struct text* login);
|
|
||||||
void load(struct desktop* desktop, struct text* login);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const main = @import("main.zig");
|
||||||
|
const ini = @import("ini.zig");
|
||||||
|
const config = @import("config.zig");
|
||||||
|
const interop = @import("interop.zig");
|
||||||
|
|
||||||
|
const DESKTOP_ENTRY_MAX_SIZE: usize = 8 * 1024;
|
||||||
|
|
||||||
|
const Entry = struct {
|
||||||
|
Desktop_Entry: struct {
|
||||||
|
Name: []const u8,
|
||||||
|
Comment: []const u8,
|
||||||
|
Exec: []const u8,
|
||||||
|
Type: []const u8,
|
||||||
|
DesktopNames: []const u8,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub export fn desktop_load(target: *main.c.struct_desktop) void {
|
||||||
|
// We don't care about desktop environments presence
|
||||||
|
// because the fallback shell is always available
|
||||||
|
// so we just dismiss any "throw" for now
|
||||||
|
var err: c_int = 0;
|
||||||
|
|
||||||
|
desktop_crawl(target, config.ly_config.ly.waylandsessions, main.c.DS_WAYLAND) catch {};
|
||||||
|
|
||||||
|
if (main.c.dgn_catch() != 0) {
|
||||||
|
err += 1;
|
||||||
|
main.c.dgn_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
desktop_crawl(target, config.ly_config.ly.xsessions, main.c.DS_XORG) catch {};
|
||||||
|
|
||||||
|
if (main.c.dgn_catch() != 0) {
|
||||||
|
err += 1;
|
||||||
|
main.c.dgn_reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(desktop: *main.c.struct_desktop, login: *main.c.struct_text) !void {
|
||||||
|
if (!config.ly_config.ly.save) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = std.fs.openFileAbsolute(config.ly_config.ly.save_file, .{ .mode = .write_only }) catch {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
var buffer = try std.fmt.allocPrint(main.allocator, "{s}\n{d}", .{ login.*.text, desktop.*.cur });
|
||||||
|
defer main.allocator.free(buffer);
|
||||||
|
|
||||||
|
try file.writeAll(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(desktop: *main.c.struct_desktop, login: *main.c.struct_text) !void {
|
||||||
|
if (!config.ly_config.ly.load) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = std.fs.openFileAbsolute(config.ly_config.ly.save_file, .{}) catch {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
var buffer = try main.allocator.alloc(u8, config.ly_config.ly.max_login_len * 2 + 1);
|
||||||
|
defer main.allocator.free(buffer);
|
||||||
|
|
||||||
|
_ = try file.readAll(buffer);
|
||||||
|
|
||||||
|
var array = std.mem.splitSequence(u8, buffer, "\n");
|
||||||
|
|
||||||
|
login.*.text = try interop.c_str(array.first()); // TODO: Free?
|
||||||
|
desktop.*.cur = try std.fmt.parseUnsigned(u16, array.next().?, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn desktop_crawl(target: *main.c.struct_desktop, sessions: []const u8, server: main.c.enum_display_server) !void {
|
||||||
|
var iterable_dir = std.fs.openIterableDirAbsolute(sessions, .{}) catch {
|
||||||
|
main.c.dgn_throw(main.c.DGN_XSESSIONS_OPEN);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer iterable_dir.close();
|
||||||
|
|
||||||
|
var iterator = iterable_dir.iterate();
|
||||||
|
|
||||||
|
var dir = std.fs.openDirAbsolute(sessions, .{}) catch {
|
||||||
|
main.c.dgn_throw(main.c.DGN_XSESSIONS_OPEN);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer dir.close();
|
||||||
|
|
||||||
|
while (try iterator.next()) |item| {
|
||||||
|
if (!std.mem.endsWith(u8, item.name, ".desktop")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = try dir.openFile(item.name, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
var buffer = try main.allocator.alloc(u8, DESKTOP_ENTRY_MAX_SIZE); // TODO: Free
|
||||||
|
var length = try file.readAll(buffer);
|
||||||
|
var entry = try ini.readToStruct(Entry, buffer[0..length]);
|
||||||
|
|
||||||
|
// TODO: If it's a wayland session, add " (Wayland)" to its name,
|
||||||
|
// as long as it doesn't already contain that string
|
||||||
|
|
||||||
|
const name = entry.Desktop_Entry.Name;
|
||||||
|
const exec = entry.Desktop_Entry.Exec;
|
||||||
|
|
||||||
|
if (name.len > 0 and exec.len > 0) {
|
||||||
|
main.c.input_desktop_add(target, (try interop.c_str(name)).ptr, (try interop.c_str(exec)).ptr, server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue