Files
fastfetch/src/fastfetch.c
T

325 lines
10 KiB
C
Raw Normal View History

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
{
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;
}