/* * xcfg | simple xorg configuration tool * MatterLinux 2023-2024 (https://matterlinux.xyz) * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "term.h" #include "util.h" #define _(x) gettext(x) bool add_startx() { bool ret = false; char *profile = ".bash_profile"; char *shellenv = getenv("SHELL"); if (NULL != shellenv && endswith(shellenv, "zsh")) profile = ".zshrc"; char profile_file[PATH_MAX]; if (!joinhome(profile_file, profile)) { error(_("Failed to get the home directory")); return ret; } FILE *pf = fopen(profile_file, "r"); if (NULL == pf) { error(_("Failed to open %s for reading"), profile_file); return ret; } char *line = NULL, *all = NULL; int indx = 0; size_t sz, len; while ((sz = getline(&line, &len, pf)) != -1) { if (strcmp(line, "#auto-startx \n") == 0) { ret = true; goto END; } if (NULL == all) { all = malloc(sz); for (int i = 0; i < sz; i++) { all[indx] = line[i]; indx++; } } else { all = realloc(all, indx + sz); for (int i = 0; i < sz; i++) { all[indx] = line[i]; indx++; } } } char *startx = AUTOSTARTX; all = realloc(all, indx + strlen(startx) + 10); for (int i = 0; i < strlen(startx); i++) { all[indx] = startx[i]; indx++; } fclose(pf); pf = fopen(profile_file, "w"); if (NULL == pf) { error(_("Failed to open %s for writing"), profile_file); goto END; } all[indx] = '\0'; if (fwrite(all, 1, indx, pf) <= 0) error(_("Failed to write to %s"), profile_file); ret = true; END: free(all); free(line); fclose(pf); return ret; } int main(int argc, char **argv, char **envp) { if (getuid() == 0) { error(_("You should use this script as a regular user, not as root!")); return EXIT_FAILURE; } signal(SIGINT, SIG_IGN); setlocale(LC_ALL, ""); textdomain("xcfg"); struct Desktop desktops[] = { { .name = "XFCE4", .desc = _("Lightweight desktop environment for UNIX-like operating " "systems"), .pkg = "xfce4", .cmd = "startxfce4\n", }, { .name = "LXDE", .desc = _("Free desktop environment with comparatively low resource " "requirements"), .pkg = "lxde", .cmd = "startlxde\n", }, {.name = "bspwm", .desc = _("Tiling window manager based on binary space partitioning"), .pkg = "bspwm", .cmd = "bspwm\n"}, {.name = "i3", .desc = _("Improved tiling window manager"), .pkg = "i3", .cmd = "i3\n"} }; char *mpi_path = check_path("mp-install"); if (NULL == mpi_path) { error(_("mp is not installed!")); return EXIT_FAILURE; } free(mpi_path); char *doas_path = check_path("doas"); if (NULL == doas_path) { doas_path = check_path("sudo"); if (NULL == doas_path) { error(_("Install doas or sudo to use this script")); free(mpi_path); return EXIT_FAILURE; } } term_init(); int sz = sizeof(desktops) / sizeof(struct Desktop); ITEM **items = malloc(sizeof(ITEM *) * (sz + 1)); for (int i = 0; i < sz; i++) items[i] = new_item(desktops[i].name, desktops[i].desc); items[sz] = NULL; int indx = term_ask(_("Choose a desktop enviroment"), items, sz + 1); for (int i = 0; i < sz; i++) free_item(items[i]); free(items); clear(); bool autox = term_yn(_("Add auto-startx to shell configuration?")); term_finish(); if (autox && !add_startx()) goto FAIL; char xinitrc[PATH_MAX]; if (!joinhome(xinitrc, ".xinitrc")) { error(_("Failed to get the home directory")); goto FAIL; } FILE *xf = fopen(xinitrc, "w"); if (fwrite(desktops[indx].cmd, 1, strlen(desktops[indx].cmd), xf) < 0) { error(_("Failed to write to %s"), xinitrc); fclose(xf); goto FAIL; } fclose(xf); success(_("Configuration has been saved!")); info(_("Installing %s"), desktops[indx].name, mpi_path); char *args[] = {doas_path, "mp-install", desktops[indx].pkg, NULL}; if (execvp(doas_path, args) != 0) { error(_("Installation failed")); } FAIL: free(doas_path); return EXIT_FAILURE; }