mirror of https://github.com/fairyglade/ly
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
4.0 KiB
C
264 lines
4.0 KiB
C
#include "configator.h"
|
|
#include "dragonfail.h"
|
|
|
|
#include "inputs.h"
|
|
#include "config.h"
|
|
#include "utils.h"
|
|
|
|
#include <dirent.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
|
|
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
|
#include <sys/consio.h>
|
|
#else // linux
|
|
#include <linux/vt.h>
|
|
#endif
|
|
|
|
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 ((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;
|
|
|
|
void hostname(char** out)
|
|
{
|
|
if (hostname_backup != NULL)
|
|
{
|
|
*out = hostname_backup;
|
|
return;
|
|
}
|
|
|
|
int maxlen = sysconf(_SC_HOST_NAME_MAX);
|
|
|
|
if (maxlen < 0)
|
|
{
|
|
maxlen = _POSIX_HOST_NAME_MAX;
|
|
}
|
|
|
|
hostname_backup = malloc(maxlen + 1);
|
|
|
|
if (hostname_backup == NULL)
|
|
{
|
|
dgn_throw(DGN_ALLOC);
|
|
return;
|
|
}
|
|
|
|
if (gethostname(hostname_backup, maxlen) < 0)
|
|
{
|
|
dgn_throw(DGN_HOSTNAME);
|
|
return;
|
|
}
|
|
|
|
hostname_backup[maxlen] = '\0';
|
|
*out = hostname_backup;
|
|
}
|
|
|
|
void free_hostname()
|
|
{
|
|
free(hostname_backup);
|
|
}
|
|
|
|
void switch_tty(struct term_buf* buf)
|
|
{
|
|
FILE* console = fopen(config.console_dev, "w");
|
|
|
|
if (console == NULL)
|
|
{
|
|
buf->info_line = lang.err_console_dev;
|
|
return;
|
|
}
|
|
|
|
int fd = fileno(console);
|
|
|
|
ioctl(fd, VT_ACTIVATE, config.tty);
|
|
ioctl(fd, VT_WAITACTIVE, config.tty);
|
|
|
|
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);
|
|
}
|