2024-02-20 18:12:54 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
* xcfg | simple xorg configuration tool
|
2024-03-24 10:20:46 +00:00
|
|
|
* MatterLinux 2023-2024 (https://matterlinux.xyz)
|
2024-02-20 18:12:54 +00:00
|
|
|
|
|
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
#include <curses.h>
|
2024-02-20 18:12:54 +00:00
|
|
|
#include <libintl.h>
|
|
|
|
#include <limits.h>
|
2024-04-22 23:28:22 +00:00
|
|
|
#include <locale.h>
|
|
|
|
#include <menu.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
2024-02-20 18:12:54 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2024-04-22 23:28:22 +00:00
|
|
|
#include <sys/wait.h>
|
2024-02-21 19:42:13 +00:00
|
|
|
#include <unistd.h>
|
2024-04-22 23:28:22 +00:00
|
|
|
|
2024-02-20 18:12:54 +00:00
|
|
|
#include "log.h"
|
2024-04-22 23:28:22 +00:00
|
|
|
#include "term.h"
|
|
|
|
#include "util.h"
|
2024-02-20 18:12:54 +00:00
|
|
|
|
|
|
|
#define _(x) gettext(x)
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
bool add_startx() {
|
2024-02-20 18:12:54 +00:00
|
|
|
bool ret = false;
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
char *profile = ".bash_profile";
|
|
|
|
char *shellenv = getenv("SHELL");
|
2024-02-20 18:12:54 +00:00
|
|
|
if (NULL != shellenv && endswith(shellenv, "zsh"))
|
|
|
|
profile = ".zshrc";
|
|
|
|
|
|
|
|
char profile_file[PATH_MAX];
|
2024-04-22 23:28:22 +00:00
|
|
|
if (!joinhome(profile_file, profile)) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Failed to get the home directory"));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
FILE *pf = fopen(profile_file, "r");
|
|
|
|
if (NULL == pf) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Failed to open %s for reading"), profile_file);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
char *line = NULL, *all = NULL;
|
2024-02-20 18:12:54 +00:00
|
|
|
int indx = 0;
|
|
|
|
size_t sz, len;
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
while ((sz = getline(&line, &len, pf)) != -1) {
|
|
|
|
if (strcmp(line, "#auto-startx \n") == 0) {
|
2024-02-20 18:12:54 +00:00
|
|
|
ret = true;
|
|
|
|
goto END;
|
|
|
|
}
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
if (NULL == all) {
|
2024-02-20 18:12:54 +00:00
|
|
|
all = malloc(sz);
|
2024-04-22 23:28:22 +00:00
|
|
|
for (int i = 0; i < sz; i++) {
|
2024-02-20 18:12:54 +00:00
|
|
|
all[indx] = line[i];
|
|
|
|
indx++;
|
|
|
|
}
|
2024-04-22 23:28:22 +00:00
|
|
|
} else {
|
|
|
|
all = realloc(all, indx + sz);
|
|
|
|
for (int i = 0; i < sz; i++) {
|
2024-02-20 18:12:54 +00:00
|
|
|
all[indx] = line[i];
|
|
|
|
indx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
char *startx = AUTOSTARTX;
|
|
|
|
all = realloc(all, indx + strlen(startx) + 10);
|
|
|
|
for (int i = 0; i < strlen(startx); i++) {
|
2024-02-20 18:12:54 +00:00
|
|
|
all[indx] = startx[i];
|
|
|
|
indx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(pf);
|
|
|
|
pf = fopen(profile_file, "w");
|
2024-04-22 23:28:22 +00:00
|
|
|
if (NULL == pf) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Failed to open %s for writing"), profile_file);
|
2024-04-22 23:28:22 +00:00
|
|
|
goto END;
|
2024-02-20 18:12:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
all[indx] = '\0';
|
2024-04-22 23:28:22 +00:00
|
|
|
if (fwrite(all, 1, indx, pf) <= 0)
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Failed to write to %s"), profile_file);
|
|
|
|
ret = true;
|
|
|
|
|
|
|
|
END:
|
|
|
|
free(all);
|
|
|
|
free(line);
|
|
|
|
fclose(pf);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
int main(int argc, char **argv, char **envp) {
|
|
|
|
if (getuid() == 0) {
|
2024-02-22 17:31:10 +00:00
|
|
|
error(_("You should use this script as a regular user, not as root!"));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2024-02-20 18:12:54 +00:00
|
|
|
signal(SIGINT, SIG_IGN);
|
|
|
|
setlocale(LC_ALL, "");
|
2024-02-23 21:32:04 +00:00
|
|
|
textdomain("xcfg");
|
2024-02-20 18:12:54 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
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) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("mp is not installed!"));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
free(mpi_path);
|
2024-02-22 17:31:10 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
char *doas_path = check_path("doas");
|
|
|
|
if (NULL == doas_path) {
|
2024-02-20 18:12:54 +00:00
|
|
|
doas_path = check_path("sudo");
|
2024-04-22 23:28:22 +00:00
|
|
|
if (NULL == doas_path) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Install doas or sudo to use this script"));
|
|
|
|
free(mpi_path);
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
term_init();
|
2024-02-20 18:12:54 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
int sz = sizeof(desktops) / sizeof(struct Desktop);
|
|
|
|
ITEM **items = malloc(sizeof(ITEM *) * (sz + 1));
|
2024-02-20 18:12:54 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
for (int i = 0; i < sz; i++)
|
2024-02-20 18:12:54 +00:00
|
|
|
items[i] = new_item(desktops[i].name, desktops[i].desc);
|
2024-02-24 17:17:55 +00:00
|
|
|
items[sz] = NULL;
|
2024-02-20 18:12:54 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
int indx = term_ask(_("Choose a desktop enviroment"), items, sz + 1);
|
2024-02-20 18:12:54 +00:00
|
|
|
for (int i = 0; i < sz; i++)
|
|
|
|
free_item(items[i]);
|
|
|
|
free(items);
|
|
|
|
clear();
|
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
bool autox = term_yn(_("Add auto-startx to shell configuration?"));
|
2024-02-20 18:12:54 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
term_finish();
|
2024-02-20 18:12:54 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
if (autox && !add_startx())
|
2024-02-20 18:12:54 +00:00
|
|
|
goto FAIL;
|
2024-04-22 23:28:22 +00:00
|
|
|
|
2024-02-20 18:12:54 +00:00
|
|
|
char xinitrc[PATH_MAX];
|
2024-04-22 23:28:22 +00:00
|
|
|
if (!joinhome(xinitrc, ".xinitrc")) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Failed to get the home directory"));
|
|
|
|
goto FAIL;
|
|
|
|
}
|
2024-04-22 23:28:22 +00:00
|
|
|
|
|
|
|
FILE *xf = fopen(xinitrc, "w");
|
|
|
|
if (fwrite(desktops[indx].cmd, 1, strlen(desktops[indx].cmd), xf) < 0) {
|
2024-02-20 18:12:54 +00:00
|
|
|
error(_("Failed to write to %s"), xinitrc);
|
|
|
|
fclose(xf);
|
|
|
|
goto FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(xf);
|
2024-02-21 19:42:13 +00:00
|
|
|
success(_("Configuration has been saved!"));
|
|
|
|
|
|
|
|
info(_("Installing %s"), desktops[indx].name, mpi_path);
|
2024-04-22 23:28:22 +00:00
|
|
|
char *args[] = {doas_path, "mp-install", desktops[indx].pkg, NULL};
|
2024-02-21 19:42:13 +00:00
|
|
|
|
2024-04-22 23:28:22 +00:00
|
|
|
if (execvp(doas_path, args) != 0) {
|
2024-02-21 19:42:13 +00:00
|
|
|
error(_("Installation failed"));
|
|
|
|
}
|
2024-02-20 18:12:54 +00:00
|
|
|
|
|
|
|
FAIL:
|
|
|
|
free(doas_path);
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|