kfetch/src/fetch.c

333 lines
7.3 KiB
C

#include <pwd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <sys/utsname.h>
#include "fetch.h"
#include "config.h"
#include "logo.h"
#define UNUSED(x) ((void)x)
FETCH Init(void) {
FETCH fetch;
if (uname(&fetch.uts) < 0) {
fprintf(stderr, "kfetch: %s\n", strerror(errno));
exit(1);
}
memset(fetch.os_name, '\0', sizeof(fetch.os_name));
if (GetOs(fetch.os_name, sizeof(fetch.os_name)))
snprintf(fetch.os_name, sizeof(fetch.os_name), "%s", fetch.uts.sysname);
fetch.font_color = FONT_COLOR;
GetArt(&fetch, 1);
return fetch;
}
int GetOs(char *buf, size_t len) {
FILE *fp = fopen("/etc/os-release", "r");
if (fp == NULL)
return 1;
while (fgets(buf, len, fp)) {
if (!strncmp(buf, "PRETTY_NAME=\"", 5)) {
buf[strlen(buf) - 2] = '\0';
fclose(fp);
char *tmp = strdup(buf);
if (tmp == NULL)
return 1;
snprintf(buf, len, "%s", tmp + strlen("PRETTY_NAME=\""));
free(tmp);
return 0;
}
}
fclose(fp);
return 1;
}
void SetArt(FETCH *fetch, size_t size, char *pkg_cmd, char **logo, char *color, int flag) {
fetch->logo_size = size / sizeof(char *);
fetch->logo = logo;
if (flag)
fetch->pkg_cmd = pkg_cmd;
fetch->color = color;
}
void GetArt(FETCH *fetch, int flag) {
if (strstr(fetch->os_name, "Debian"))
SetArt(fetch, sizeof(Debian), "dpkg -l | tail -n+6 | wc -l | tr -d ' '", Debian, "\033[0;31m", flag);
else if (strstr(fetch->os_name, "Void"))
SetArt(fetch, sizeof(Void), "xbps-query -l | wc -l", Void, "\033[0;32m", flag);
else if (strstr(fetch->os_name, "Alpine"))
SetArt(fetch, sizeof(Alpine), "grep 'P:' /lib/apk/db/installed | wc -l", Alpine, "\033[1;34m", flag);
else if (strstr(fetch->os_name, "Arch") || strstr(fetch->os_name, "Artix"))
SetArt(fetch, sizeof(Arch), "pacman -Qq | wc -l", Arch, "\033[0;34m", flag);
else if (strstr(fetch->os_name, "PlainOs"))
SetArt(fetch, sizeof(PlainOs), NULL, PlainOs, "\033[37m", flag);
else if (strstr(fetch->os_name, "OpenBSD"))
SetArt(fetch, sizeof(OpenBSD), "/bin/ls -1 /var/db/pkg/ | wc -l | tr -d ' '", OpenBSD, "\033[1;33m", flag);
else if (strstr(fetch->os_name, "Ubuntu"))
SetArt(fetch, sizeof(Ubuntu), "dpkg -l | tail -n+6 | wc -l | tr -d ' '", Ubuntu, "\033[1;33m", flag);
else if (strstr(fetch->os_name, "Mint"))
SetArt(fetch, sizeof(Lmint), "dpkg -l | tail -n+6 | wc -l | tr -d ' '", Lmint, "\033[1;32m", flag);
else if (!chdir("/system") && !strcmp(fetch->os_name, "Linux"))
SetArt(fetch, sizeof(Android), "dpkg -l | tail -n+6 | wc -l | tr -d ' '", Android, "\033[32m", flag);
else
SetArt(fetch, sizeof(Unknow), NULL, Unknow, "\033[1;36m", flag);
}
int GetKernel(const char *title, const FETCH fetch) {
printf("%s%s%s%s", fetch.color, title, fetch.font_color, fetch.uts.release);
return 0;
}
int PrintOs(const char *title, const FETCH fetch) {
printf("%s%s%s%s", fetch.color, title, fetch.font_color, fetch.os_name);
return 0;
}
int Blank(const char *title, const FETCH fetch) {
printf("%s%s%s", fetch.color, title, fetch.font_color);
return 0;
}
int GetUser(const char *title, const FETCH fetch) {
UNUSED(fetch);
struct passwd *pw = getpwuid(geteuid());
if (pw == 0)
return 1;
printf("%s%s%s%s", fetch.color, title, fetch.font_color, pw->pw_name);
return 0;
}
int GetUptime(const char *title, const FETCH fetch) {
#ifdef CLOCK
struct timespec uptime;
if (clock_gettime(CLOCK, &uptime) == -1)
return 1;
int days = uptime.tv_sec / 86400;
int hours = uptime.tv_sec / 3600;
int mins = (uptime.tv_sec / 60) - (uptime.tv_sec / 3600 * 60);
if (days > 0)
printf("%s%s%s%d days", fetch.color, title, fetch.font_color, days);
else
printf("%s%s%s%dh %dm", fetch.color, title, fetch.font_color, hours, mins);
return 0;
#endif
return 1;
}
int GetArch(const char *title, const FETCH fetch) {
printf("%s%s%s%s", fetch.color, title, fetch.font_color, fetch.uts.machine);
return 0;
}
int GetShell(const char *title, const FETCH fetch) {
char *shell = getenv("SHELL");
if (shell == NULL)
return 1;
char *splt = strrchr(shell, '/');
if (splt == NULL)
return 1;
printf("%s%s%s%s", fetch.color, title, fetch.font_color, splt + 1);
return 0;
}
int GetPkg(const char *title, const FETCH fetch) {
if (fetch.pkg_cmd == NULL)
return 1;
FILE *fp = popen(fetch.pkg_cmd, "r");
if (fp == NULL)
return 1;
printf("%s%s%s", fetch.color, title, fetch.font_color);
int ch;
while ((ch = getc(fp))) {
if (ch == EOF || ch == '\n')
break;
putchar(ch);
}
pclose(fp);
return 0;
}
int GetMem(const char *title, const FETCH fetch) {
FILE *fp = fopen("/proc/meminfo", "r");
if (fp == NULL)
return 1;
off_t free = 0, total = 0, cached = 0, buffer = 0, unused = 0;
if (fscanf(fp, "MemTotal: %ju kB\nMemFree: %ju kB\nMemAvailable: %ju kB\nBuffers: %ju kB\nCached: %ju kB", &total, &free, &unused, &buffer, &cached) < 0)
return 1;
fclose(fp);
printf("%s%s%s%lumb / %lumb", fetch.color, title, fetch.font_color, (uintmax_t)(total - (cached + free + buffer)) / 1024, (uintmax_t)total / 1024);
return 0;
}
int GetModel(const char *title, const FETCH fetch) {
FILE *fp = NULL;
for (size_t i = 0; i < sizeof(MODELS) / sizeof(char *); i++) {
fp = fopen(MODELS[i], "r");
if (fp != NULL)
break;
}
if (fp == NULL)
return 1;
char model_buffer[MODEL_BUFF_SIZE + 1];
char *ptr = fgets(model_buffer, sizeof(model_buffer), fp);
if (ptr != NULL) {
/* del \n */
char *ptr = strchr(model_buffer, '\n');
if (ptr != NULL)
*ptr = '\0';
printf("%s%s%s%.25s", fetch.color, title, fetch.font_color, model_buffer);
}
fclose(fp);
return 0;
}
int GetHostname(const char *title, const FETCH fetch) {
char hostname[HOST_NAME_MAX + 1];
if (gethostname(hostname, sizeof(hostname)) < 0)
return 1;
printf("%s%s%s%s", fetch.color, title, fetch.font_color, hostname);
return 0;
}
int GetAVG(const char *title, const FETCH fetch) {
#ifndef __ANDROID__
double avg[3] = {0, 0, 0};
if (getloadavg(avg, sizeof(avg) / sizeof(avg[0])) < 0)
return 1;
printf("%s%s%s%.2f %.2f %.2f", fetch.color, title, fetch.font_color, avg[0], avg[1], avg[2]);
return 0;
#else
return 1;
#endif
}
void DrawBar(int cur, int max) {
int bar = max / BAR_WIDTH;
#ifdef FIRA_CODE
char *start = "";
if (cur * bar > 0)
start = "";
char *end = "";
if (cur < max)
end = "";
char *bar_filled = "";
char *bar_void = "";
#else
char *start = "[";
char *end = "]";
char *bar_filled = "#";
char *bar_void = ".";
#endif
printf("%s", start);
for (int i = 0; i < BAR_WIDTH; i++) {
if (i * bar < cur)
printf("%s", bar_filled);
else
printf("%s", bar_void);
}
printf("%s", end);
}
int GetBattery(const char *title, const FETCH fetch) {
if (BATT_NAME == NULL)
return 1;
FILE *fp = fopen(BATT_NAME, "r");
if (fp == NULL)
return 1;
int capacity = 0;
if (fscanf(fp, "%d", &capacity) < 0)
return 1;
fclose(fp);
printf("%s%s%s", fetch.color, title, fetch.font_color);
DrawBar(capacity, 100);
return 0;
}
int Execute(const char *title, const FETCH fetch) {
FILE *fp = popen(title, "r");
if (fp == NULL)
return 1;
printf("%s", fetch.font_color);
int c;
while ((c = getc(fp))) {
if (c == EOF || c == '\n')
break;
putchar(c);
}
pclose(fp);
return 0;
}
int eBlank(const char *title, const FETCH fetch) {
printf("%s%s%s", fetch.color, title, fetch.font_color);
return 1;
}