/* cfetch is my try to implement a neofetch/fastfetch/commiefetch clone in C. * Copyright (C) 2026 Anser * * cfetch 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. * * cfetch 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 . */ #include "../include/cfetch.h" #include #include #include void get_kernel(struct system_info_t *info) { #ifdef __linux__ struct utsname u; if (uname(&u) == 0) { snprintf(info->kernel, sizeof(info->kernel), "%.30s %.30s", u.sysname, u.release); } else { perror("Error while accessing uname"); return; } #endif return; } void get_cpu(struct system_info_t *info) { FILE* file = fopen("/proc/cpuinfo", "r"); //check file existence if (!file) { snprintf(info->cpu, sizeof(info->cpu), "Unknown"); return; } char line[256]; char *cpu_name = NULL; //read per line while (fgets(line, sizeof(line), file)) { char* p = strstr(line, "model name"); if (p != NULL) { cpu_name = strchr(p, ':') + 1; //skip : break; } } if (cpu_name != NULL) { snprintf(info->cpu, sizeof(info->cpu), "%s", trim_whitespace(cpu_name)); } fclose(file); return; } void get_memory(struct system_info_t *info) { FILE *file = fopen("/proc/meminfo", "r"); if (!file) { snprintf(info->memory, sizeof(info->memory), "Unknown"); return; } char line[256]; long total = 0; long available = 0; // read per line while (fgets(line, sizeof(line), file)) { if (sscanf(line, "MemTotal: %ld kB", &total) == 1) continue; if (sscanf(line, "MemAvailable: %ld kB", &available) == 1) continue; } fclose(file); snprintf(info->memory, sizeof(info->memory), "Memory %.2f GB / %.2f GB", (total - available) / (1024.0 * 1024.0), total / (1024.0 * 1024.0)); return; } bool get_os_release_value(char *line, const char *key, char *buffer, size_t size_out) { if (!line || !key || !buffer || size_out == 0) return false; size_t key_len = strlen(key); if (key_len == 0) return false; if (strncmp(line, key, key_len) != 0) return false; // '=' pointer char *eq = strchr(line, '='); if (!eq) return false; char *val = trim_whitespace(eq + 1); if (*val == '"' || *val == '\'') { char quote = *val; // safe which char was used val++; char *end = strchr(val, quote); if (end != NULL) { *end = '\0'; } else { char *nl = strchr(val, '\n'); if (nl) *nl = '\0'; } } else { char *nl = strchr(val, '\n'); if (nl) *nl = '\0'; } snprintf(buffer, size_out, "%s", val); return true; } void get_os_release(struct system_info_t *info) { FILE *file; char line[256]; char id[64] = { 0 }; char version_id[64] = { 0 }; char pretty_name[64] = { 0 }; file = fopen("/etc/os-release", "r"); if (!file) { file = fopen("/usr/lib/os-release", "r"); } if (!file) { snprintf(info->distro, sizeof(info->distro), "Unknown"); return; } // get ID, PRETTY_NAME, VERSION_ID while (fgets(line, sizeof(line), file)) { if (get_os_release_value(line, "ID", id, sizeof(id))) continue; if (get_os_release_value(line, "PRETTY_NAME", pretty_name, sizeof(pretty_name))) continue; if (get_os_release_value(line, "VERSION_ID", version_id, sizeof(version_id))) continue; } // set OS if (pretty_name[0] != '\0') { snprintf(info->distro, sizeof(info->distro), "%s", pretty_name); } else if (id[0] != '\0' && version_id[0] != '\0') { snprintf(info->distro, sizeof(info->distro), "%s %s", id, version_id); } fclose(file); return; }