#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include "config.h"
#include "logo/colors.h"
#if defined(__OpenBSD__)
#include "logo/openbsd.h"
#elif defined(__NetBSD__)
#include "logo/netbsd.h"
#elif defined(__FreeBSD__)
#include "logo/freebsd.h"
#elif defined(__linux__)
#include "logo/linux.h"
#include "distro.h"
#elif defined(__sun)
#include "logo/sunos.h"
#elif defined(__APPLE__)
#include "logo/macos.h"
#elif defined(__HAIKU__)
#include "logo/haiku.h"
#endif
bool islogob = true;
bool islogos = false;
bool islogod = true;
bool islogocustom = false;
#if defined(__linux__) || defined(__sunos)
bool islogodistro = false;
char *distrostring;
#endif
bool isos = true;
bool ishost = true;
#if defined(__linux__) || defined(__sunos)
bool isdistro = true;
#endif
bool isuptime = true;
#if defined(__OpenBSD__)
bool isrecording = true;
#endif
bool ispackages = true;
bool islibc = true;
bool isresolution = true;
bool iswm = true;
bool isshell = true;
bool iscpu = true;
bool isgpu = true;
bool ismemory = true;
bool isstorage = true;
bool isbiglogo = false;
bool issmalllogo = false;
bool mkbiglogo = false;
bool mksmalllogo = false;
size_t biglogoi = 0;
size_t smalllogoi = 0;
const char *customcolor;
const char *customtitlecolor;
const char *customlogobig;
const char *customlogosmall;
void rmstr(char *str, const char *sub) {
char *pos;
size_t len = strlen(sub);
while ((pos = strstr(str, sub)) != NULL) {
memmove(pos, pos + len, strlen(pos + len) + 1);
}
}
const char *applycolor(const char *color) {
if (strncmp(color, "grey", 4) == 0) return GREY;
else if (strncmp(color, "red", 3) == 0) return RED;
else if (strncmp(color, "green", 5) == 0) return GREEN;
else if (strncmp(color, "yellow", 6) == 0) return YELLOW;
else if (strncmp(color, "blue", 4) == 0) return BLUE;
else if (strncmp(color, "magenta", 7) == 0) return MAGENTA;
else if (strncmp(color, "cyan", 4) == 0) return CYAN;
else if (strncmp(color, "white", 5) == 0) return WHITE;
return RESET;
}
char *colrep(const char *str, const char *old, const char *new) {
char *res;
int i, count = 0;
int nlen = strlen(new);
int olen = strlen(old);
for (i = 0; str[i] != '\0'; i++) {
if (strstr(&str[i], old) == &str[i]) {
count++;
i += olen - 1;
}
}
res = (char *)malloc(i + count * (nlen - olen) + 1);
if (!res) {
return NULL;
}
i = 0;
while (*str) {
if (strstr(str, old) == str) {
memcpy(&res[i], new, strlen(new));
i += nlen;
str += olen;
} else {
res[i++] = *str++;
}
}
res[i] = '\0';
return res;
}
bool containvocab(const char *line, const char *word) {
const char *p = line;
size_t len = strlen(word);
while ((p = strstr(p, word)) != NULL) {
if (
(p == line || !isalnum((unsigned char)p[-1])) &&
!isalnum((unsigned char)p[len])
) return true;
p += len;
}
return false;
}
void getconf() {
char *homedir = getenv("HOME");
if (homedir == NULL) {
perror("ホームディレクトリを受取に失敗");
return;
}
#if defined(__HAIKU__)
char *basedir = "/config/settings/";
#else
char *basedir = "/.config/";
#endif
int alllen = snprintf(NULL, 0, "%s%s%s", homedir, basedir, "farfetch.conf") + 1;
char *cnfpath = malloc(alllen);
if (cnfpath == NULL) {
perror("メモリを割当に失敗");
return;
}
snprintf(cnfpath, alllen, "%s%s%s", homedir, basedir, "farfetch.conf");
if (access(cnfpath, F_OK) != 0) {
free(cnfpath);
return;
}
FILE *file = fopen(cnfpath, "r");
free(cnfpath);
if (!file) {
return;
}
char line[256];
while (fgets(line, sizeof(line), file)) {
if (line[0] == '#' || line[0] == '\n') continue;
if (strstr(line, "hide ") != NULL) {
if (containvocab(line, "logo")) islogod = false;
if (containvocab(line, "os")) isos = false;
if (containvocab(line, "host")) ishost = false;
#if defined(__linux__) || defined(__sunos)
if (containvocab(line, "distro")) isdistro = false;
#endif
if (containvocab(line, "uptime")) isuptime = false;
#if defined (__OpenBSD__)
if (containvocab(line, "recording")) isrecording = false;
#endif
if (containvocab(line, "packages")) ispackages = false;
if (containvocab(line, "libc")) islibc = false;
if (containvocab(line, "resolution")) isresolution = false;
if (containvocab(line, "wm")) iswm = false;
if (containvocab(line, "shell")) isshell = false;
if (containvocab(line, "cpu")) iscpu = false;
if (containvocab(line, "gpu")) isgpu = false;
if (containvocab(line, "memory")) ismemory = false;
if (containvocab(line, "storage")) isstorage = false;
}
// 色
if (strstr(line, "set color") != NULL) {
char color[10];
sscanf(line, "set color %s", color);
customcolor = applycolor(color);
}
if (strstr(line, "set titlecolor") != NULL) {
char color[10];
sscanf(line, "set titlecolor %s", color);
customtitlecolor = applycolor(color);
}
// デフォルトは大きいロゴ
if (strstr(line, "show logo") != NULL) {
if (containvocab(line, "small")) {
islogob = false;
islogos = true;
} else {
islogob = true;
islogos = false;
}
if (containvocab(line, "custom")) {
islogocustom = true;
#if defined(__linux__) || defined(__sunos)
} else {
distrostring = strdup(line);
if (!distrostring) {
perror("メモリの役割に失敗");
return;
}
rmstr(distrostring, "show logo");
if (containvocab(line, "small")) rmstr(distrostring, "small");
else rmstr(distrostring, "big");
rmstr(distrostring, "\n");
rmstr(distrostring, " ");
if (is_distro(distrostring)) islogodistro = true;
else distrostring = NULL;
#endif
}
}
// カスタムロゴ
if (strstr(line, "define custom big logo:") != NULL) {
mkbiglogo = true;
}
if (strstr(line, "define custom small logo:") != NULL) {
mksmalllogo = true;
}
if (mkbiglogo && islogocustom && islogob) {
isbiglogo = true;
if (strstr(line, "define custom big logo:") != NULL) {
continue;
} else if (strstr(line, "EOL") != NULL) {
mkbiglogo = false;
} else if (biglogoi < logosize) {
LOGO[biglogoi] = strdup(line);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[GREY]", GREY);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[RED]", RED);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[GREEN]", GREEN);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[YELLOW]", YELLOW);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[BLUE]", BLUE);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[MAGENTA]", MAGENTA);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[CYAN]", CYAN);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[WHITE]", WHITE);
LOGO[biglogoi] = colrep(LOGO[biglogoi], "[RESET]", RESET);
size_t len = strlen(LOGO[biglogoi]);
if (len > 0 && LOGO[biglogoi][len - 1] == '\n') {
LOGO[biglogoi][len - 1] = '\0';
}
biglogoi++;
free(LOGO[biglogoi]);
}
}
if (mksmalllogo && islogocustom && islogos) {
issmalllogo = true;
if (strstr(line, "define custom small logo:") != NULL) {
continue;
} else if (strstr(line, "EOL") != NULL) {
mksmalllogo = false;
} else if (smalllogoi < MIN_SIZE) {
LOGO_SMALL[smalllogoi] = strdup(line);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[GREY]", GREY);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[RED]", RED);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[GREEN]", GREEN);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[YELLOW]", YELLOW);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[BLUE]", BLUE);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[MAGENTA]", MAGENTA);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[CYAN]", CYAN);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[WHITE]", WHITE);
LOGO_SMALL[smalllogoi] = colrep(LOGO_SMALL[smalllogoi], "[RESET]", RESET);
size_t len = strlen(LOGO_SMALL[smalllogoi]);
if (len > 0 && LOGO_SMALL[smalllogoi][len - 1] == '\n') {
LOGO_SMALL[smalllogoi][len - 1] = '\0';
}
smalllogoi++;
free(LOGO[smalllogoi]);
}
}
}
fclose(file);
return;
}