2021-02-18 22:25:36 +01:00
|
|
|
#include "fastfetch.h"
|
2021-02-22 20:36:25 +01:00
|
|
|
#include "fastfetch_config.h"
|
2021-02-18 22:25:36 +01:00
|
|
|
|
2021-02-27 20:31:54 +01:00
|
|
|
#include <malloc.h>
|
2021-02-27 20:50:13 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <unistd.h>
|
2021-02-27 20:31:54 +01:00
|
|
|
#include <sys/stat.h>
|
2021-02-27 20:50:13 +01:00
|
|
|
#include <fcntl.h>
|
2021-02-22 16:52:51 +01:00
|
|
|
|
2021-02-19 16:23:41 +01:00
|
|
|
static void printHelp()
|
|
|
|
|
{
|
|
|
|
|
puts(
|
|
|
|
|
"usage: fastfetch <options>\n"
|
2021-02-20 19:32:57 +01:00
|
|
|
"\n"
|
2021-02-20 20:00:06 +01:00
|
|
|
" -h, --help: shows this message and exits\n"
|
|
|
|
|
" -h <command>, --help <command>: shows help for a specific command and exits\n"
|
2021-02-22 20:36:25 +01:00
|
|
|
" -v --version prints the version of fastfetch and exits\n"
|
2021-02-20 20:00:06 +01:00
|
|
|
" -l <name>, --logo <name>: sets the shown logo. Also changes the main color accordingly\n"
|
|
|
|
|
" -c <color>, --color <color>: sets the color of the keys. Must be a linux console color code\n"
|
|
|
|
|
" -s <width>, --seperator <width>: sets the distance between logo and text\n"
|
2021-02-25 18:38:00 +01:00
|
|
|
" -x <offset>, --offsetx <offset>: sets the x offset. Can be negative to cut the logo, but no more than logo width.\n"
|
|
|
|
|
" --no-color: disables all colors. This MUST be before -l/--logo or --print-logos\n"
|
|
|
|
|
" --no-color-logo: disables the coloring of the logo. This MUST be before -l/--logo or --print-logos\n"
|
2021-02-22 16:52:51 +01:00
|
|
|
" -r --recache: dont use cached values and generate new ones\n"
|
2021-02-20 20:00:06 +01:00
|
|
|
" --show-errors: if an error occurs, show it instead of discarding the category\n"
|
|
|
|
|
" --list-logos: lists the names of available logos and exits\n"
|
|
|
|
|
" --print-logos: prints available logos and exits\n"
|
2021-02-19 16:23:41 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-20 19:32:57 +01:00
|
|
|
static void printCommandHelpColor()
|
|
|
|
|
{
|
|
|
|
|
puts(
|
|
|
|
|
"usage: fastfetch --color <color>\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"<color> must be a color encoding for linux terminals. It is inserted between \"ESC[\" and \"m\".\n"
|
|
|
|
|
"Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors.\n"
|
|
|
|
|
"Examples:\n"
|
|
|
|
|
" \"--color 35\": sets the color to pink\n"
|
|
|
|
|
" \"--color 4;92\": sets the color to bright Green with underline\n"
|
|
|
|
|
" \"--color 5;104\": blinking text on a blue background\n"
|
2021-02-20 20:00:06 +01:00
|
|
|
"If no color is set, the main color of the logo will be used.\n"
|
2021-02-20 19:32:57 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void printCommandHelp(const char* command)
|
|
|
|
|
{
|
2021-02-27 21:10:27 +01:00
|
|
|
if(strcasecmp(command, "c") == 0 || strcasecmp(command, "-c") == 0 || strcasecmp(command, "color") == 0 || strcasecmp(command, "--color") == 0)
|
2021-02-20 19:32:57 +01:00
|
|
|
printCommandHelpColor();
|
|
|
|
|
else
|
|
|
|
|
printf("No specific help for command %s provided\n", command);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-27 18:30:05 +01:00
|
|
|
static void parseArguments(int argc, char** argv, FFconfig* config)
|
2021-02-22 13:45:14 +01:00
|
|
|
{
|
2021-02-25 18:38:00 +01:00
|
|
|
bool colorText = true;
|
2021-02-27 20:31:54 +01:00
|
|
|
int logoIndex = -1;
|
2021-02-25 18:38:00 +01:00
|
|
|
|
2021-02-19 16:23:41 +01:00
|
|
|
for(int i = 1; i < argc; i++)
|
|
|
|
|
{
|
2021-02-27 21:10:27 +01:00
|
|
|
if(strcasecmp(argv[i], "-h") == 0 || strcasecmp(argv[i], "--help") == 0)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
2021-02-20 19:32:57 +01:00
|
|
|
if(i == argc - 1)
|
|
|
|
|
printHelp();
|
|
|
|
|
else
|
|
|
|
|
printCommandHelp(argv[i + 1]);
|
|
|
|
|
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(0);
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "-v") == 0 || strcasecmp(argv[i], "--version") == 0)
|
2021-02-22 20:36:25 +01:00
|
|
|
{
|
|
|
|
|
puts(FASTFETCH_PROJECT_NAME" "FASTFETCH_PROJECT_VER);
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "--list-logos") == 0)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
|
|
|
|
ffListLogos();
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(0);
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "--print-logos") == 0)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
2021-02-27 18:30:05 +01:00
|
|
|
ffPrintLogos(config->colorLogo);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(0);
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "--show-errors") == 0)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
2021-02-27 18:30:05 +01:00
|
|
|
config->showErrors = true;
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "-l") == 0 || strcasecmp(argv[i], "--logo") == 0)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
|
|
|
|
if(i == argc - 1)
|
|
|
|
|
{
|
|
|
|
|
printf("Error: usage: %s <logo>\n", argv[i]);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(41);
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-27 20:31:54 +01:00
|
|
|
logoIndex = i + 1;
|
2021-02-19 16:23:41 +01:00
|
|
|
++i;
|
|
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "-c") == 0 || strcasecmp(argv[i], "--color") == 0)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
|
|
|
|
if(i == argc - 1)
|
|
|
|
|
{
|
|
|
|
|
printf("Error: usage: %s <color>\n", argv[i]);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(42);
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
|
|
|
|
size_t len = strlen(argv[i + 1]);
|
2021-02-22 19:34:34 +01:00
|
|
|
if(len > 28)
|
2021-02-19 16:23:41 +01:00
|
|
|
{
|
2021-02-22 19:34:34 +01:00
|
|
|
printf("Error: max color string length is 28, %zu given\n", len);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(43);
|
2021-02-20 20:00:06 +01:00
|
|
|
}
|
2021-02-27 18:30:05 +01:00
|
|
|
sprintf(config->color, "\033[%sm", argv[i + 1]);
|
2021-02-20 20:00:06 +01:00
|
|
|
++i;
|
|
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "-s") == 0 || strcasecmp(argv[i], "--seperator") == 0)
|
2021-02-20 20:00:06 +01:00
|
|
|
{
|
|
|
|
|
if(i == argc -1)
|
|
|
|
|
{
|
|
|
|
|
printf("Error: usage: %s <width>\n", argv[i]);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(44);
|
2021-02-20 20:00:06 +01:00
|
|
|
}
|
2021-02-27 18:30:05 +01:00
|
|
|
if(sscanf(argv[i + 1], "%hd", &config->logo_seperator) != 1)
|
2021-02-20 20:00:06 +01:00
|
|
|
{
|
2021-02-20 20:12:57 +01:00
|
|
|
printf("Error: couldn't parse %s to uint16_t\n", argv[i + 1]);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(45);
|
2021-02-20 20:00:06 +01:00
|
|
|
}
|
2021-02-19 16:23:41 +01:00
|
|
|
++i;
|
|
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "-x") == 0 || strcasecmp(argv[i], "--offsetx") == 0)
|
2021-02-25 18:38:00 +01:00
|
|
|
{
|
|
|
|
|
if(i == argc -1)
|
|
|
|
|
{
|
|
|
|
|
printf("Error: usage: %s <offset>\n", argv[i]);
|
|
|
|
|
exit(46);
|
|
|
|
|
}
|
2021-02-27 18:30:05 +01:00
|
|
|
if(sscanf(argv[i + 1], "%hi", &config->offsetx) != 1)
|
2021-02-25 18:38:00 +01:00
|
|
|
{
|
|
|
|
|
printf("Error: couldn't parse %s to int16_t\n", argv[i + 1]);
|
|
|
|
|
exit(47);
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "-r") == 0 || strcasecmp(argv[i], "--recache") == 0)
|
2021-02-22 16:52:51 +01:00
|
|
|
{
|
2021-02-27 18:30:05 +01:00
|
|
|
config->recache = true;
|
2021-02-22 16:52:51 +01:00
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "--no-color") == 0)
|
2021-02-25 18:38:00 +01:00
|
|
|
{
|
|
|
|
|
colorText = false;
|
2021-02-27 18:30:05 +01:00
|
|
|
config->colorLogo = false;
|
2021-02-25 18:38:00 +01:00
|
|
|
}
|
2021-02-27 21:10:27 +01:00
|
|
|
else if(strcasecmp(argv[i], "--no-color-logo") == 0)
|
2021-02-25 18:38:00 +01:00
|
|
|
{
|
2021-02-27 18:30:05 +01:00
|
|
|
config->colorLogo = false;
|
2021-02-25 18:38:00 +01:00
|
|
|
}
|
2021-02-19 16:38:54 +01:00
|
|
|
else
|
|
|
|
|
{
|
2021-02-20 20:00:06 +01:00
|
|
|
printf("Error: unknown option: %s\n", argv[i]);
|
2021-02-22 13:45:14 +01:00
|
|
|
exit(40);
|
2021-02-19 16:38:54 +01:00
|
|
|
}
|
2021-02-19 16:23:41 +01:00
|
|
|
}
|
2021-02-25 18:38:00 +01:00
|
|
|
|
2021-02-27 20:31:54 +01:00
|
|
|
//Load logo after parsing because of --no-color and --no-color-logo
|
|
|
|
|
if(logoIndex >= 0)
|
|
|
|
|
ffLoadLogoSet(config, argv[logoIndex]);
|
|
|
|
|
else
|
|
|
|
|
ffLoadLogo(config);
|
|
|
|
|
|
|
|
|
|
//We need to do this after loading the logo
|
2021-02-25 18:38:00 +01:00
|
|
|
if(colorText)
|
2021-02-27 18:30:05 +01:00
|
|
|
strcpy(config->color, config->logo.color);
|
2021-02-25 18:38:00 +01:00
|
|
|
else
|
2021-02-27 18:30:05 +01:00
|
|
|
config->color[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void defaultConfig(FFconfig* config)
|
|
|
|
|
{
|
|
|
|
|
config->logo_seperator = 4;
|
|
|
|
|
config->offsetx = 0;
|
|
|
|
|
config->titleLength = 20; // This is overwritten by ffPrintTitle
|
|
|
|
|
config->colorLogo = true;
|
|
|
|
|
config->showErrors = false;
|
|
|
|
|
config->recache = false;
|
2021-02-22 13:45:14 +01:00
|
|
|
}
|
|
|
|
|
|
2021-02-27 20:31:54 +01:00
|
|
|
static FILE* createStructureFile(const char* filename)
|
|
|
|
|
{
|
|
|
|
|
FILE* f = fopen(filename, "wr");
|
|
|
|
|
|
|
|
|
|
fputs(
|
|
|
|
|
"Title\n"
|
|
|
|
|
"Seperator\n"
|
|
|
|
|
"OS\n"
|
|
|
|
|
"Host\n"
|
|
|
|
|
"Kernel\n"
|
|
|
|
|
"Uptime\n"
|
|
|
|
|
"Packages\n"
|
|
|
|
|
"Shell\n"
|
|
|
|
|
"Resolution\n"
|
|
|
|
|
"DesktopEnvironment\n"
|
|
|
|
|
"Theme\n"
|
|
|
|
|
"Icons\n"
|
|
|
|
|
"Font\n"
|
|
|
|
|
"Terminal\n"
|
|
|
|
|
"CPU\n"
|
|
|
|
|
"GPU\n"
|
|
|
|
|
"Memory\n"
|
|
|
|
|
"Disk\n"
|
|
|
|
|
"Battery\n"
|
|
|
|
|
"Locale\n"
|
|
|
|
|
"Break\n"
|
|
|
|
|
"Colors\n"
|
|
|
|
|
,f);
|
|
|
|
|
|
|
|
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parseLine(FFinstance* instance, const char* line)
|
|
|
|
|
{
|
|
|
|
|
if(strcasecmp(line, "break") == 0)
|
|
|
|
|
ffPrintBreak(instance);
|
|
|
|
|
else if(strcasecmp(line, "title") == 0)
|
|
|
|
|
ffPrintTitle(instance);
|
|
|
|
|
else if(strcasecmp(line, "seperator") == 0)
|
|
|
|
|
ffPrintSeperator(instance);
|
|
|
|
|
else if(strcasecmp(line, "os") == 0)
|
|
|
|
|
ffPrintOS(instance);
|
|
|
|
|
else if(strcasecmp(line, "host") == 0)
|
|
|
|
|
ffPrintHost(instance);
|
|
|
|
|
else if(strcasecmp(line, "kernel") == 0)
|
|
|
|
|
ffPrintKernel(instance);
|
|
|
|
|
else if(strcasecmp(line, "uptime") == 0)
|
|
|
|
|
ffPrintUptime(instance);
|
|
|
|
|
else if(strcasecmp(line, "packages") == 0)
|
|
|
|
|
ffPrintPackages(instance);
|
|
|
|
|
else if(strcasecmp(line, "shell") == 0)
|
|
|
|
|
ffPrintShell(instance);
|
|
|
|
|
else if(strcasecmp(line, "resolution") == 0)
|
|
|
|
|
ffPrintResolution(instance);
|
|
|
|
|
else if(strcasecmp(line, "desktopenvironment") == 0 || strcasecmp(line, "de") == 0)
|
|
|
|
|
ffPrintDesktopEnvironment(instance);
|
|
|
|
|
else if(strcasecmp(line, "theme") == 0)
|
|
|
|
|
ffPrintTheme(instance);
|
|
|
|
|
else if(strcasecmp(line, "icons") == 0)
|
|
|
|
|
ffPrintIcons(instance);
|
|
|
|
|
else if(strcasecmp(line, "font") == 0)
|
|
|
|
|
ffPrintFont(instance);
|
|
|
|
|
else if(strcasecmp(line, "terminal") == 0)
|
|
|
|
|
ffPrintTerminal(instance);
|
|
|
|
|
else if(strcasecmp(line, "cpu") == 0)
|
|
|
|
|
ffPrintCPU(instance);
|
|
|
|
|
else if(strcasecmp(line, "gpu") == 0)
|
|
|
|
|
ffPrintGPU(instance);
|
|
|
|
|
else if(strcasecmp(line, "memory") == 0)
|
|
|
|
|
ffPrintMemory(instance);
|
|
|
|
|
else if(strcasecmp(line, "disk") == 0)
|
|
|
|
|
ffPrintDisk(instance);
|
|
|
|
|
else if(strcasecmp(line, "battery") == 0)
|
|
|
|
|
ffPrintBattery(instance);
|
|
|
|
|
else if(strcasecmp(line, "locale") == 0)
|
|
|
|
|
ffPrintLocale(instance);
|
|
|
|
|
else if(strcasecmp(line, "colors") == 0)
|
|
|
|
|
ffPrintColors(instance);
|
|
|
|
|
else
|
|
|
|
|
ffPrintError(instance, line, "<no implementaion provided>");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void parseStructureFile(FFinstance* instance)
|
|
|
|
|
{
|
2021-02-27 20:50:13 +01:00
|
|
|
char configFolder[256];
|
|
|
|
|
strcpy(configFolder, instance->state.passwd->pw_dir);
|
|
|
|
|
strcat(configFolder, "/.config");
|
2021-02-27 20:31:54 +01:00
|
|
|
|
2021-02-27 20:50:13 +01:00
|
|
|
mkdir(configFolder, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a config folder but whow knews
|
2021-02-27 20:31:54 +01:00
|
|
|
|
2021-02-27 20:50:13 +01:00
|
|
|
strcat(configFolder, "/fastfetch/");
|
|
|
|
|
mkdir(configFolder, S_IRWXU | S_IRGRP | S_IROTH);
|
2021-02-27 20:31:54 +01:00
|
|
|
|
2021-02-27 20:50:13 +01:00
|
|
|
char valueDir[256];
|
|
|
|
|
strcpy(valueDir, configFolder);
|
|
|
|
|
strcat(valueDir, "values/");
|
|
|
|
|
mkdir(valueDir, S_IRWXU | S_IRGRP | S_IROTH);
|
|
|
|
|
|
2021-02-27 20:31:54 +01:00
|
|
|
char structureFileName[256];
|
2021-02-27 20:50:13 +01:00
|
|
|
strcpy(structureFileName, configFolder);
|
2021-02-27 20:31:54 +01:00
|
|
|
strcat(structureFileName, "structure");
|
|
|
|
|
|
|
|
|
|
FILE* structureFile;
|
|
|
|
|
if(access(structureFileName, F_OK) != 0)
|
|
|
|
|
structureFile = createStructureFile(structureFileName);
|
|
|
|
|
else
|
|
|
|
|
structureFile = fopen(structureFileName, "r");
|
|
|
|
|
|
|
|
|
|
char* line = NULL;
|
|
|
|
|
size_t len;
|
|
|
|
|
ssize_t read;
|
|
|
|
|
|
|
|
|
|
while ((read = getline(&line, &len, structureFile)) != -1)
|
|
|
|
|
{
|
|
|
|
|
if(line[read - 1] == '\n')
|
|
|
|
|
line[read - 1] = '\0';
|
2021-02-27 21:04:50 +01:00
|
|
|
|
2021-02-28 17:10:12 +01:00
|
|
|
ffTrimTrailingWhitespace(line);
|
2021-02-27 20:50:13 +01:00
|
|
|
|
2021-02-28 17:10:12 +01:00
|
|
|
if(!ffPrintCustomValue(instance, line))
|
2021-02-27 20:50:13 +01:00
|
|
|
parseLine(instance, line);
|
2021-02-27 20:31:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(line);
|
|
|
|
|
fclose(structureFile);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-22 13:45:14 +01:00
|
|
|
int main(int argc, char** argv)
|
|
|
|
|
{
|
2021-02-27 18:30:05 +01:00
|
|
|
FFinstance instance;
|
|
|
|
|
ffInitState(&instance.state);
|
|
|
|
|
defaultConfig(&instance.config);
|
|
|
|
|
parseArguments(argc, argv, &instance.config);
|
2021-02-27 20:31:54 +01:00
|
|
|
parseStructureFile(&instance);
|
2021-02-18 22:25:36 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|