#include "configator.h" #include "dragonfail.h" #include "inputs.h" #include "config.h" #include "utils.h" #include #include #include #include #include #include #include #include #if defined(__DragonFly__) || defined(__FreeBSD__) #include #else // linux #include #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 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; 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); }