diff --git a/uwufetch.c b/uwufetch.c deleted file mode 100644 index a8a8800..0000000 --- a/uwufetch.c +++ /dev/null @@ -1,1489 +0,0 @@ -/* - * UwUfetch 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. - * - * This program 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 . - */ - -#ifndef UWUFETCH_VERSION - #define UWUFETCH_VERSION "unkown" // needs to be changed by the build script -#endif - -#define _GNU_SOURCE // for strcasestr - -#ifdef __APPLE__ - #include // for checking iOS -#endif -#include -#include -#include -#include -#include -#include -#if defined(__APPLE__) || defined(__BSD__) - #include - #if defined(__OPENBSD__) - #include - #else - #include - #endif // defined(__OPENBSD__) -#else // defined(__APPLE__) || defined(__BSD__) - #ifdef __BSD__ - #else // defined(__BSD__) || defined(_WIN32) - #ifndef _WIN32 - #ifndef __OPENBSD__ - #include - #else // __OPENBSD__ - #endif // __OPENBSD__ - #else // _WIN32 - #include - #endif // _WIN32 - #endif // defined(__BSD__) || defined(_WIN32) -#endif // defined(__APPLE__) || defined(__BSD__) -#ifndef _WIN32 - #include - #include -#else // _WIN32 - #include -CONSOLE_SCREEN_BUFFER_INFO csbi; -#endif // _WIN32 - -// COLORS -#define NORMAL "\x1b[0m" -#define BOLD "\x1b[1m" -#define BLACK "\x1b[30m" -#define RED "\x1b[31m" -#define GREEN "\x1b[32m" -#define SPRING_GREEN "\x1b[38;5;120m" -#define YELLOW "\x1b[33m" -#define BLUE "\x1b[34m" -#define MAGENTA "\x1b[0;35m" -#define CYAN "\x1b[36m" -#define WHITE "\x1b[37m" -#define PINK "\x1b[38;5;201m" -#define LPINK "\x1b[38;5;213m" - -#ifdef _WIN32 - #define BLOCK_CHAR "\xdb" // block char for colors -#else // _WIN32 - #define BLOCK_CHAR "\u2587" -#endif // _WIN32 -#ifdef __APPLE__ - // buffers where data fetched from sysctl are stored - // CPU - #define CPUBUFFERLEN 128 - -char cpu_buffer[CPUBUFFERLEN]; -size_t cpu_buffer_len = CPUBUFFERLEN; - -// Installed RAM -int64_t mem_buffer = 0; -size_t mem_buffer_len = sizeof(mem_buffer); - -// uptime -struct timeval time_buffer; -size_t time_buffer_len = sizeof(time_buffer); -#endif // __APPLE__ - -struct package_manager { - char command_string[128]; // command to get number of packages installed - char pkgman_name[16]; // name of the package manager -}; - -// all configuration flags available -struct configuration { - int - // when (0) ascii is printed, when (1) image is printed - ascii_image_flag, - show_user_info, // all the following flags are 1 (true) by default - show_os, - show_host, - show_kernel, - show_cpu, - // if show_gpu[0] == -2, all gpus are shown, if == -3 no gpu is shown - show_gpu[256], - show_ram, - show_resolution, - show_shell, - show_pkgs, - show_uptime, - show_colors; -}; - -// info that will be printed with the logo -struct info { - char user[128], // username - host[256], // hostname (computer name) - shell[64], // shell name - model[256], // model name - kernel[256], // kernel name (linux 5.x-whatever) - os_name[64], // os name (arch linux, windows, mac os) - cpu_model[256], - gpu_model[64][256], - pkgman_name[64], // package managers string - image_name[128], - *config_directory, // configuration directory name - *cache_content; // cache file content - int target_width, // for the truncate_str function - screen_width, - screen_height, - ram_total, - ram_used, - pkgs; // full package count - long uptime; - -#ifndef _WIN32 - struct utsname sys_var; -#endif // _WIN32 -#ifndef __APPLE__ - #ifdef __linux__ - struct sysinfo sys; - #else // __linux__ - #ifdef _WIN32 - struct _SYSTEM_INFO sys; - #endif // _WIN32 - #endif // __linux__ -#endif // __APPLE__ -#ifndef _WIN32 - struct winsize win; -#else // _WIN32 - int ws_col, ws_rows; -#endif // _WIN32 -}; - -#ifdef _WIN32 -char* MOVE_CURSOR = "\033[21C"; // moves the cursor after printing the image or the ascii logo -#else -char* MOVE_CURSOR = "\033[18C"; -#endif - -// reads the config file -struct configuration parse_config(struct info* user_info) { - char buffer[256]; // buffer for the current line - // enabling all flags by default - struct configuration config_flags; - memset(&config_flags, 1, sizeof(config_flags)); - memset(&config_flags.show_gpu, -1, 256 * sizeof(int)); // -1 means 'undefined' - config_flags.show_gpu[0] = -2; // show all gpus - config_flags.ascii_image_flag = 0; - - FILE* config = NULL; // config file pointer - if (user_info->config_directory == NULL) { // if config directory is not set, try to open the default - if (getenv("HOME") != NULL) { - char homedir[512]; - sprintf(homedir, "%s/.config/uwufetch/config", getenv("HOME")); - config = fopen(homedir, "r"); - if (!config) { - if (getenv("PREFIX") != NULL) { - char prefixed_etc[512]; - sprintf(prefixed_etc, "%s/etc/uwufetch/config", getenv("PREFIX")); - config = fopen(prefixed_etc, "r"); - } else - config = fopen("/etc/uwufetch/config", "r"); - } - } - } else - config = fopen(user_info->config_directory, "r"); - if (config == NULL) return config_flags; // if config file does not exist, return the defaults - - int gpu_cfg_count = 0; - - // reading the config file - while (fgets(buffer, sizeof(buffer), config)) { - sscanf(buffer, "distro=%s", user_info->os_name); - if (sscanf(buffer, "ascii=%[truefalse]", buffer)) - config_flags.ascii_image_flag = !strcmp(buffer, "false"); - if (sscanf(buffer, "image=\"%[^\"]\"", user_info->image_name)) { - if (user_info->image_name[0] == '~') { // replacing the ~ character with the home directory - memmove(&user_info->image_name[0], &user_info->image_name[1], strlen(user_info->image_name)); // remove the first char - char temp[128] = "/home/"; - strcat(temp, user_info->user); - strcat(temp, user_info->image_name); - sprintf(user_info->image_name, "%s", temp); - } - config_flags.ascii_image_flag = 1; // enable the image flag - } - - // reading other values - if (sscanf(buffer, "user=%[truefalse]", buffer)) - config_flags.show_user_info = !strcmp(buffer, "true"); - if (sscanf(buffer, "os=%[truefalse]", buffer)) - config_flags.show_os = strcmp(buffer, "false"); - if (sscanf(buffer, "host=%[truefalse]", buffer)) - config_flags.show_host = strcmp(buffer, "false"); - if (sscanf(buffer, "kernel=%[truefalse]", buffer)) - config_flags.show_kernel = strcmp(buffer, "false"); - if (sscanf(buffer, "cpu=%[truefalse]", buffer)) - config_flags.show_cpu = strcmp(buffer, "false"); - if (sscanf(buffer, "gpu=%d", &config_flags.show_gpu[gpu_cfg_count])) // enabling single gpu - gpu_cfg_count++; - if (sscanf(buffer, "gpu=%[truefalse]", buffer)) { // enabling all gpus - if (strcmp(buffer, "false") == 0) - config_flags.show_gpu[0] = -3; // disable all gpus - } - if (sscanf(buffer, "ram=%[truefalse]", buffer)) - config_flags.show_ram = strcmp(buffer, "false"); - if (sscanf(buffer, "resolution=%[truefalse]", buffer)) - config_flags.show_resolution = strcmp(buffer, "false"); - if (sscanf(buffer, "shell=%[truefalse]", buffer)) - config_flags.show_shell = strcmp(buffer, "false"); - if (sscanf(buffer, "pkgs=%[truefalse]", buffer)) - config_flags.show_pkgs = strcmp(buffer, "false"); - if (sscanf(buffer, "uptime=%[truefalse]", buffer)) - config_flags.show_uptime = strcmp(buffer, "false"); - if (sscanf(buffer, "colors=%[truefalse]", buffer)) - config_flags.show_colors = strcmp(buffer, "false"); - } - fclose(config); - return config_flags; -} - -// gets the installed package count and package managers name -#ifdef _WIN32 -int pkgman(struct info* user_info, struct configuration* config_flags) -#else // _WIN32 -int pkgman(struct info* user_info) -#endif -{ // this is just a function that returns the total of installed packages - int total = 0; - -#ifndef __APPLE__ - // this function is not used on mac os because it causes lots of problems - #ifndef _WIN32 - // all supported package managers - struct package_manager pkgmans[] = - {{"apt list --installed 2> /dev/null | wc -l", "(apt)"}, - {"apk info 2> /dev/null | wc -l", "(apk)"}, - // {"dnf list installed 2> /dev/null | wc -l", "(dnf)"}, // according to https://stackoverflow.com/questions/48570019/advantages-of-dnf-vs-rpm-on-fedora, dnf and rpm return the same number of packages - {"qlist -I 2> /dev/null | wc -l", "(emerge)"}, - {"flatpak list 2> /dev/null | wc -l", "(flatpak)"}, - {"snap list 2> /dev/null | wc -l", "(snap)"}, - {"guix package --list-installed 2> /dev/null | wc -l", "(guix)"}, - {"nix-store -q --requisites /run/current-system/sw 2> /dev/null | wc -l", "(nix)"}, - {"pacman -Qq 2> /dev/null | wc -l", "(pacman)"}, - {"pkg info 2>/dev/null | wc -l", "(pkg)"}, - {"pkg_info 2>/dev/null | wc -l | sed \"s/ //g\"", "(pkg)"}, - {"port installed 2> /dev/null | tail -n +2 | wc -l", "(port)"}, - {"brew list 2> /dev/null | wc -l", "(brew)"}, - {"rpm -qa --last 2> /dev/null | wc -l", "(rpm)"}, - {"xbps-query -l 2> /dev/null | wc -l", "(xbps)"}, - {"zypper -q se --installed-only 2> /dev/null | wc -l", "(zypper)"}}; - const int pkgman_count = sizeof(pkgmans) / sizeof(pkgmans[0]); // number of package managers - int comma_separator = 0; - for (int i = 0; i < pkgman_count; i++) { - struct package_manager* current = &pkgmans[i]; // pointer to current package manager - - FILE* fp = popen(current->command_string, "r"); // trying current package manager - unsigned int pkg_count = 0; - - if (fscanf(fp, "%u", &pkg_count) == 3) continue; // if a number is found, continue the loop - pclose(fp); - - // adding a package manager with its package count to user_info->pkgman_name - total += pkg_count; - if (pkg_count > 0) { - if (comma_separator++) strcat(user_info->pkgman_name, ", "); - char spkg_count[16]; - sprintf(spkg_count, "%u", pkg_count); - strcat(user_info->pkgman_name, spkg_count); - strcat(user_info->pkgman_name, " "); - strcat(user_info->pkgman_name, current->pkgman_name); - } - } - #else // _WIN32 - // chocolatey for windows - if (config_flags->show_pkgs) { - FILE* fp = popen("choco list -l --no-color 2> nul", "r"); - unsigned int pkg_count; - char buffer[7562] = {0}; - while (fgets(buffer, sizeof(buffer), fp)) { - sscanf(buffer, "%u packages installed.", &pkg_count); - } - if (fp) pclose(fp); - - total = pkg_count; - char spkg_count[16]; - sprintf(spkg_count, "%u", pkg_count); - strcat(user_info->pkgman_name, spkg_count); - strcat(user_info->pkgman_name, " "); - strcat(user_info->pkgman_name, "(chocolatey)"); - } - #endif // _WIN32 - -#endif - return total; -} - -#ifdef __APPLE__ -// gets the uptime for mac os -int uptime_apple() { - int mib[2] = {CTL_KERN, KERN_BOOTTIME}; - sysctl(mib, 2, &time_buffer, &time_buffer_len, NULL, 0); - - time_t bsec = time_buffer.tv_sec; - time_t csec = time(NULL); - - return difftime(csec, bsec); -} -#endif - -#ifdef __BSD__ -// gets the uptime for freebsd -int uptime_freebsd() { // this code is from coreutils uptime: https://github.com/coreutils/coreutils/blob/master/src/uptime.c - int boot_time = 0; - static int request[2] = {CTL_KERN, KERN_BOOTTIME}; - struct timeval result; - size_t result_len = sizeof result; - - if (sysctl(request, 2, &result, &result_len, NULL, 0) >= 0) - boot_time = result.tv_sec; - int time_now = time(NULL); - return time_now - boot_time; -} -#endif - -// prints logo (as an image) of the given system. -void print_image(struct info* user_info) { -#ifndef __IPHONE__ - char command[256]; - if (strlen(user_info->image_name) > 1) - sprintf(command, "viu -t -w 18 -h 8 %s 2> /dev/null", user_info->image_name); // creating the command to show the image - else { - if (strcmp(user_info->os_name, "android") == 0) - sprintf(command, "viu -t -w 18 -h 8 /data/data/com.termux/files/usr/lib/uwufetch/%s.png 2> /dev/null", user_info->os_name); // image command for android - else if (strcmp(user_info->os_name, "macos") == 0) - sprintf(command, "viu -t -w 18 -h 8 /usr/local/lib/uwufetch/%s.png 2> /dev/null", user_info->os_name); - else - sprintf(command, "viu -t -w 18 -h 8 /usr/lib/uwufetch/%s.png 2> /dev/null", user_info->os_name); // image command for other systems - } - printf("\n"); - if (system(command) != 0) // if viu is not installed or the image is missing - printf("\033[0E\033[3C%s\n" - " There was an\n" - " error: viu\n" - " is not installed\n" - " or the image\n" - " is not found\n" - " Read IMAGES.md\n" - " for more info.\n\n", - RED); -#else - // unfortunately, the iOS stdlib does not have - // system(); - // because it reports that it is not available under iOS during compilation - printf("\033[0E\033[3C%s\n" - " There was an\n" - " error: images\n" - " are currently\n" - " disabled on iOS.\n\n", - RED); -#endif -} - -// uwufies distro name -void uwu_name(struct configuration* config_flags, struct info* user_info) { -#define STRING_TO_UWU(original, uwufied) \ - if (strcmp(user_info->os_name, original) == 0) \ - sprintf(user_info->os_name, "%s", uwufied) - - // linux - STRING_TO_UWU("alpine", "Nyalpine"); - else STRING_TO_UWU("amogos", "AmogOwOS"); - else STRING_TO_UWU("arch", "Nyarch Linuwu"); - else STRING_TO_UWU("arcolinux", "ArcOwO Linuwu"); - else STRING_TO_UWU("artix", "Nyartix Linuwu"); - else STRING_TO_UWU("debian", "Debinyan"); - else STRING_TO_UWU("endeavouros", "endeavOwO"); - else STRING_TO_UWU("EndeavourOS", "endeavOwO"); - else STRING_TO_UWU("fedora", "Fedowa"); - else STRING_TO_UWU("gentoo", "GentOwO"); - else STRING_TO_UWU("gnu", "gnUwU"); - else STRING_TO_UWU("guix", "gnUwU gUwUix"); - else STRING_TO_UWU("linuxmint", "LinUWU Miwint"); - else STRING_TO_UWU("manjaro", "Myanjawo"); - else STRING_TO_UWU("manjaro-arm", "Myanjawo AWM"); - else STRING_TO_UWU("neon", "KDE NeOwOn"); - else STRING_TO_UWU("nixos", "nixOwOs"); - else STRING_TO_UWU("opensuse-leap", "OwOpenSUSE Leap"); - else STRING_TO_UWU("opensuse-tumbleweed", "OwOpenSUSE Tumbleweed"); - else STRING_TO_UWU("pop", "PopOwOS"); - else STRING_TO_UWU("raspbian", "RaspNyan"); - else STRING_TO_UWU("slackware", "Swackwawe"); - else STRING_TO_UWU("solus", "sOwOlus"); - else STRING_TO_UWU("ubuntu", "Uwuntu"); - else STRING_TO_UWU("void", "OwOid"); - else STRING_TO_UWU("xerolinux", "xuwulinux"); - else STRING_TO_UWU("android", "Nyandroid"); // android at the end because it could be not considered as an actual distribution of gnu/linux - - // BSD - else STRING_TO_UWU("freebsd", "FweeBSD"); - else STRING_TO_UWU("openbsd", "OwOpenBSD"); - // Apple family - else STRING_TO_UWU("macos", "macOwOS"); - else STRING_TO_UWU("ios", "iOwOS"); - - // Windows - else STRING_TO_UWU("windows", "WinyandOwOws"); - - else { - sprintf(user_info->os_name, "%s", "unknown"); // replacing the original os name with the uwufied version - if (config_flags->ascii_image_flag == 1) { - print_image(user_info); - printf("\n"); - } - } -#undef STRING_TO_UWU -} - -// prints all the collected info and returns the number of printed lines -int print_info(struct configuration* config_flags, struct info* user_info) { - int line_count = 0; -#ifdef _WIN32 - // prints without overflowing the terminal width - #define responsively_printf(buf, format, ...) \ - { \ - sprintf(buf, format, __VA_ARGS__); \ - printf("%.*s\n", user_info->ws_col - 1, buf); \ - line_count++; \ - } -#else // _WIN32 - // prints without overflowing the terminal width - #define responsively_printf(buf, format, ...) \ - { \ - sprintf(buf, format, __VA_ARGS__); \ - printf("%.*s\n", user_info->win.ws_col - 1, buf); \ - line_count++; \ - } -#endif // _WIN32 - char print_buf[1024]; // for responsively print - - // print collected info - from host to cpu info - printf("\033[9A"); // to align info text - if (config_flags->show_user_info) - responsively_printf(print_buf, "%s%s%s%s@%s", MOVE_CURSOR, - NORMAL, BOLD, user_info->user, user_info->host); - uwu_name(config_flags, user_info); - if (config_flags->show_os) - responsively_printf(print_buf, "%s%s%sOWOS %s%s", - MOVE_CURSOR, NORMAL, BOLD, NORMAL, - user_info->os_name); - if (config_flags->show_host) - responsively_printf(print_buf, "%s%s%sMOWODEL %s%s", - MOVE_CURSOR, NORMAL, BOLD, NORMAL, - user_info->model); - if (config_flags->show_kernel) - responsively_printf(print_buf, "%s%s%sKEWNEL %s%s", - MOVE_CURSOR, NORMAL, BOLD, NORMAL, - user_info->kernel); - if (config_flags->show_cpu) - responsively_printf(print_buf, "%s%s%sCPUWU %s%s", - MOVE_CURSOR, NORMAL, BOLD, NORMAL, - user_info->cpu_model); - - if (config_flags->show_gpu[0] == -2) { // print all gpu models - for (int i = 0; i < 256 && user_info->gpu_model[i][0]; i++) { - responsively_printf(print_buf, "%s%s%sGPUWU %s%s", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->gpu_model[i]); - } - } else if (config_flags->show_gpu[0] != -3) { // print only the configured gpu models - for (int i = 0; i < 256; i++) { - if (config_flags->show_gpu[i] >= 0) - if (user_info->gpu_model[config_flags->show_gpu[i]][0]) - responsively_printf(print_buf, "%s%s%sGPUWU %s%s", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->gpu_model[config_flags->show_gpu[i]]); - } - } - - if (config_flags->show_ram) // print ram - responsively_printf(print_buf, "%s%s%sMEMOWY %s%i MiB/%i MiB", MOVE_CURSOR, NORMAL, BOLD, NORMAL, (user_info->ram_used), user_info->ram_total); - if (config_flags->show_resolution) // print resolution - if (user_info->screen_width != 0 || user_info->screen_height != 0) - responsively_printf(print_buf, "%s%s%sWESOWUTION%s %dx%d", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->screen_width, user_info->screen_height); - if (config_flags->show_shell) // print shell name - responsively_printf(print_buf, "%s%s%sSHEWW %s%s", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->shell); -#if defined(__APPLE__) && !defined(__IPHONE__) // some time ago __IPHONE__ was defined as TARGET_OS_IPHONE, but it was defined also in m1 macs, so I changed it - if (config_flags->show_pkgs) // print pkgs for mac os - system("ls $(brew --cellar) | wc -l | awk -F' ' '{print \" \x1b[34m \x1b[0m\x1b[1mPKGS\x1b[0m \"$1 \" (brew)\"}'"); -#else - if (config_flags->show_pkgs) // print pkgs - responsively_printf(print_buf, "%s%s%sPKGS %s%s%d: %s", MOVE_CURSOR, NORMAL, BOLD, NORMAL, NORMAL, user_info->pkgs, user_info->pkgman_name); -#endif - if (config_flags->show_uptime) { // print uptime - if (user_info->uptime == 0) { - -#ifdef __APPLE__ - user_info->uptime = uptime_apple(); -#else - #ifdef __BSD__ - user_info->uptime = uptime_freebsd(); - #else - #ifdef _WIN32 - user_info->uptime = GetTickCount() / 1000; - #else // _WIN32 - user_info->uptime = user_info->sys.uptime; - #endif // _WIN32 - #endif -#endif - } - switch (user_info->uptime) { // formatting the uptime which is store in seconds - case 0 ... 3599: - responsively_printf(print_buf, "%s%s%sUWUPTIME %s%lim", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->uptime / 60 % 60); - break; - case 3600 ... 86399: - responsively_printf(print_buf, "%s%s%sUWUPTIME %s%lih, %lim", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->uptime / 3600, user_info->uptime / 60 % 60); - break; - default: - responsively_printf(print_buf, "%s%s%sUWUPTIME %s%lid, %lih, %lim", MOVE_CURSOR, NORMAL, BOLD, NORMAL, user_info->uptime / 86400, user_info->uptime / 3600 % 24, user_info->uptime / 60 % 60); - } - } - if (config_flags->show_colors) // print colors - printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - MOVE_CURSOR, BOLD, BLACK, BLOCK_CHAR, BLOCK_CHAR, RED, - BLOCK_CHAR, BLOCK_CHAR, GREEN, BLOCK_CHAR, BLOCK_CHAR, YELLOW, - BLOCK_CHAR, BLOCK_CHAR, BLUE, BLOCK_CHAR, BLOCK_CHAR, MAGENTA, - BLOCK_CHAR, BLOCK_CHAR, CYAN, BLOCK_CHAR, BLOCK_CHAR, WHITE, - BLOCK_CHAR, BLOCK_CHAR, NORMAL); - return line_count; -} - -// writes cache to cache file -void write_cache(struct info* user_info) { - char cache_file[512]; - sprintf(cache_file, "%s/.cache/uwufetch.cache", getenv("HOME")); // default cache file location - FILE* cache_fp = fopen(cache_file, "w"); - if (cache_fp == NULL) { - fprintf(stderr, "Failed to write to %s!", cache_file); - return; - } - // writing all info to the cache file -#ifdef __APPLE__ - user_info->uptime = uptime_apple(); -#else - #ifdef __BSD__ - user_info->uptime = uptime_freebsd(); - #else - #ifndef _WIN32 - user_info->uptime = user_info->sys.uptime; - #endif // _WIN32 - #endif -#endif - fprintf( // writing most of the values to config file - cache_fp, - "user=%s\nhost=%s\nversion_name=%s\nhost_model=%s\nkernel=%s\ncpu=%" - "s\nscreen_width=%d\nscreen_height=%d\nshell=%s\npkgs=%d\npkgman_name=%" - "s\n", - user_info->user, user_info->host, user_info->os_name, - user_info->model, user_info->kernel, user_info->cpu_model, - user_info->screen_width, user_info->screen_height, user_info->shell, - user_info->pkgs, user_info->pkgman_name); - - for (int i = 0; user_info->gpu_model[i][0]; i++) // writing gpu names to file - fprintf(cache_fp, "gpu=%s\n", user_info->gpu_model[i]); - -#ifdef __APPLE__ - /* char brew_command[2048]; - sprintf(brew_command, "ls $(brew --cellar) | wc -l | awk -F' ' '{print \" - \x1b[34mw w \x1b[0m\x1b[1mPKGS\x1b[0m \"$1 \" (brew)\"}' - > %s", cache_file); system(brew_command); */ -#endif - fclose(cache_fp); - return; -} - -// reads cache file if it exists -int read_cache(struct info* user_info) { - char cache_file[512]; - sprintf(cache_file, "%s/.cache/uwufetch.cache", getenv("HOME")); // cache file location - FILE* cache_fp = fopen(cache_file, "r"); - if (cache_fp == NULL) return 0; - char buffer[256]; // line buffer - int gpuc = 0; // gpu counter - while (fgets(buffer, sizeof(buffer), cache_fp)) { // reading the file - sscanf(buffer, "user=%99[^\n]", user_info->user); - sscanf(buffer, "host=%99[^\n]", user_info->host); - sscanf(buffer, "version_name=%99[^\n]", user_info->os_name); - sscanf(buffer, "host_model=%99[^\n]", user_info->model); - sscanf(buffer, "kernel=%99[^\n]", user_info->kernel); - sscanf(buffer, "cpu=%99[^\n]", user_info->cpu_model); - if (sscanf(buffer, "gpu=%99[^\n]", user_info->gpu_model[gpuc]) != 0) - gpuc++; - sscanf(buffer, "screen_width=%i", &user_info->screen_width); - sscanf(buffer, "screen_height=%i", &user_info->screen_height); - sscanf(buffer, "shell=%99[^\n]", user_info->shell); - sscanf(buffer, "pkgs=%i", &user_info->pkgs); - sscanf(buffer, "pkgman_name=%99[^\n]", user_info->pkgman_name); - } - - fclose(cache_fp); - return 1; -} - -/* - This replaces all terms in a string with another term. - replace("Hello World!", "World", "everyone") - This returns "Hello everyone!". - */ -void replace(char* original, char* search, char* replacer) { - char* ch; - char buffer[1024]; - while ((ch = strstr(original, search))) { - ch = strstr(original, search); - strncpy(buffer, original, ch - original); - buffer[ch - original] = 0; - sprintf(buffer + (ch - original), "%s%s", replacer, ch + strlen(search)); - original[0] = 0; - strcpy(original, buffer); - } -} - -/* - This replaces all terms in a string with another term, case insensitive - replace("Hello wOrLd!", "WoRlD", "everyone") - This returns "Hello everyone!". - */ -void replace_ignorecase(char* original, char* search, char* replacer) { - char* ch; - char buffer[1024]; -#ifdef _WIN32 - #define strcasestr(o, s) strstr(o, s) -#endif - while ((ch = strcasestr(original, search))) { - strncpy(buffer, original, ch - original); - buffer[ch - original] = 0; - sprintf(buffer + (ch - original), "%s%s", replacer, ch + strlen(search)); - original[0] = 0; - strcpy(original, buffer); - } -} - -// prints logo (as ascii art) of the given system. -void print_ascii(struct info* user_info) { - printf("\n"); - FILE* file; - char ascii_file[1024]; - // First tries to get ascii art file from local directory. Useful for debugging - sprintf(ascii_file, "./res/ascii/%s.txt", user_info->os_name); - file = fopen(ascii_file, "r"); - if (!file) { // if the file does not exist in the local directory, open it from the installation directory - if (strcmp(user_info->os_name, "android") == 0) - sprintf(ascii_file, "/data/data/com.termux/files/usr/lib/uwufetch/ascii/%s.txt", user_info->os_name); - else if (strcmp(user_info->os_name, "macos") == 0) - sprintf(ascii_file, "/usr/local/lib/uwufetch/ascii/%s.txt", user_info->os_name); - else - sprintf(ascii_file, "/usr/lib/uwufetch/ascii/%s.txt", user_info->os_name); - - file = fopen(ascii_file, "r"); - if (!file) { - // Prevent infinite loops - if (strcmp(user_info->os_name, "unknown") == 0) { - printf("No\nunknown\nascii\nfile\n\n\n\n"); - return; - } - sprintf(user_info->os_name, "unknown"); // current os is not supported - return print_ascii(user_info); - } - } - char buffer[256]; // line buffer - while (fgets(buffer, 256, file)) { // replacing color placecholders - replace(buffer, "{NORMAL}", NORMAL); - replace(buffer, "{BOLD}", BOLD); - replace(buffer, "{BLACK}", BLACK); - replace(buffer, "{RED}", RED); - replace(buffer, "{GREEN}", GREEN); - replace(buffer, "{SPRING_GREEN}", SPRING_GREEN); - replace(buffer, "{YELLOW}", YELLOW); - replace(buffer, "{BLUE}", BLUE); - replace(buffer, "{MAGENTA}", MAGENTA); - replace(buffer, "{CYAN}", CYAN); - replace(buffer, "{WHITE}", WHITE); - replace(buffer, "{PINK}", PINK); - replace(buffer, "{LPINK}", LPINK); - replace(buffer, "{BLOCK}", BLOCK_CHAR); - replace(buffer, "{BLOCK_VERTICAL}", BLOCK_CHAR); - replace(buffer, "{BACKGROUND_GREEN}", "\e[0;42m"); - replace(buffer, "{BACKGROUND_RED}", "\e[0;41m"); - replace(buffer, "{BACKGROUND_WHITE}", "\e[0;47m"); - printf("%s", buffer); // print the line after setting the color - } - // Always set color to NORMAL, so there's no need to do this in every ascii file. - printf(NORMAL); - fclose(file); -} - -// prints the info after reading the cache file and returns the count of printed lines -int print_cache(struct configuration* config_flags, struct info* user_info) { -#ifndef __APPLE__ - #ifndef _WIN32 - #ifndef __BSD__ - sysinfo(&user_info->sys); // to get uptime - #endif - #endif - FILE* meminfo; - - #ifdef __BSD__ - meminfo = popen("LANG=EN_us freecolor -om 2> /dev/null", "r"); // free alternative - #else - // getting memory info from /proc/meminfo: https://github.com/KittyKatt/screenFetch/issues/386#issuecomment-249312716 - meminfo = fopen("/proc/meminfo", "r"); // popen("LANG=EN_us free -m 2> /dev/null", "r"); // get ram info with free - #endif - // brackets are here to restrict the access to this int variables, which are temporary - { - char buffer[256]; - int memtotal = 0, shmem = 0, memfree = 0, buffers = 0, cached = 0, sreclaimable = 0; - while (fgets(buffer, sizeof(buffer), meminfo)) { - sscanf(buffer, "MemTotal: %d", &memtotal); - sscanf(buffer, "Shmem: %d", &shmem); - sscanf(buffer, "MemFree: %d", &memfree); - sscanf(buffer, "Buffers: %d", &buffers); - sscanf(buffer, "Cached: %d", &cached); - sscanf(buffer, "SReclaimable: %d", &sreclaimable); - } - user_info->ram_total = memtotal / 1024; - user_info->ram_used = ((memtotal + shmem) - (memfree + buffers + cached + sreclaimable)) / 1024; - } - - // char line[256]; - // while (fgets(line, sizeof(line), meminfo)) // old way to get ram usage that uses the "free" command - // // free command prints like this: "Mem:" total used free shared buff/cache available - // sscanf(line, "Mem: %d %d", &user_info->ram_total, &user_info->ram_used); - fclose(meminfo); -#elif defined(_WIN32) - FILE* mem_used_fp; - mem_used_fp = popen("wmic OS GET FreePhysicalMemory", "r"); // free does not exist for windows - char mem_used_ch[2137]; - printf("\n\n\n\\\n"); - while (fgets(mem_used_ch, sizeof(mem_used_ch), mem_used_fp) != NULL) printf("%s\n", mem_used_ch); - pclose(mem_used_fp); - int mem_used = atoi(mem_used_ch); - ram_used = mem_used / 1024; - -#else // __APPLE__ - - // Used ram - FILE *mem_wired_fp, *mem_active_fp, *mem_compressed_fp; - mem_wired_fp = popen("vm_stat | awk '/wired/ { printf $4 }' | cut -d '.' -f 1", "r"); - mem_active_fp = popen("vm_stat | awk '/active/ { printf $3 }' | cut -d '.' -f 1", "r"); - mem_compressed_fp = popen("vm_stat | awk '/occupied/ { printf $5 }' | cut -d '.' -f 1", "r"); - char mem_wired_ch[2137], mem_active_ch[2137], mem_compressed_ch[2137]; - while (fgets(mem_wired_ch, sizeof(mem_wired_ch), mem_wired_fp) != NULL) - while (fgets(mem_active_ch, sizeof(mem_active_ch), mem_active_fp) != NULL) - while (fgets(mem_compressed_ch, sizeof(mem_compressed_ch), mem_compressed_fp) != NULL) - ; - - pclose(mem_wired_fp); - pclose(mem_active_fp); - pclose(mem_compressed_fp); - - int mem_wired = atoi(mem_wired_ch); - int mem_active = atoi(mem_active_ch); - int mem_compressed = atoi(mem_compressed_ch); - - // Total ram - sysctlbyname("hw.memsize", &mem_buffer, &mem_buffer_len, NULL, 0); - user_info->ram_used = ((mem_wired + mem_active + mem_compressed) * 4 / 1024); - -#endif // __APPLE__ - print_ascii(user_info); - return print_info(config_flags, user_info); -} - -// truncates the given string -void truncate_str(char* string, int target_width) { - char arr[target_width]; - for (int i = 0; i < target_width; i++) arr[i] = string[i]; - string = arr; -} - -// remove square brackets (for gpu names) -void remove_brackets(char* str) { - int i = 0, j = 0; - while (i < (int)strlen(str)) - if (str[i] == '[' || str[i] == ']') - for (j = i; j < (int)strlen(str); j++) str[j] = str[j + 1]; - else - i++; -} - -#ifdef _WIN32 -// windows sucks and hasn't a strstep, so I copied one from -// https://stackoverflow.com/questions/8512958/is-there-a-windows-variant-of-strsep-function -char* strsep(char** stringp, const char* delim) { - char* start = *stringp; - char* p; - p = (start != NULL) ? strpbrk(start, delim) : NULL; - if (p == NULL) - *stringp = NULL; - else { - *p = '\0'; - *stringp = p + 1; - } - return start; -} -#endif - -// uwufies kernel name -void uwu_kernel(char* kernel) { -#define KERNEL_TO_UWU(str, original, uwufied) \ - if (strcmp(str, original) == 0) sprintf(str, "%s", uwufied) - - char* temp_kernel = kernel; - char* token; - char splitted[16][128] = {}; - - int count = 0; - while ((token = strsep(&temp_kernel, " "))) { // split kernel name - strcpy(splitted[count], token); - count++; - } - strcpy(kernel, ""); - for (int i = 0; i < 16; i++) { - // replace kernel name with uwufied version - KERNEL_TO_UWU(splitted[i], "Linux", "Linuwu"); - else KERNEL_TO_UWU(splitted[i], "linux", "linuwu"); - else KERNEL_TO_UWU(splitted[i], "alpine", "Nyalpine"); - else KERNEL_TO_UWU(splitted[i], "amogos", "AmogOwOS"); - else KERNEL_TO_UWU(splitted[i], "arch", "Nyarch Linuwu"); - else KERNEL_TO_UWU(splitted[i], "artix", "Nyartix Linuwu"); - else KERNEL_TO_UWU(splitted[i], "debian", "Debinyan"); - else KERNEL_TO_UWU(splitted[i], "endeavouros", "endeavOwO"); - else KERNEL_TO_UWU(splitted[i], "EndeavourOS", "endeavOwO"); - else KERNEL_TO_UWU(splitted[i], "fedora", "Fedowa"); - else KERNEL_TO_UWU(splitted[i], "gentoo", "GentOwO"); - else KERNEL_TO_UWU(splitted[i], "gnu", "gnUwU"); - else KERNEL_TO_UWU(splitted[i], "guix", "gnUwU gUwUix"); - else KERNEL_TO_UWU(splitted[i], "linuxmint", "LinUWU Miwint"); - else KERNEL_TO_UWU(splitted[i], "manjaro", "Myanjawo"); - else KERNEL_TO_UWU(splitted[i], "manjaro-arm", "Myanjawo AWM"); - else KERNEL_TO_UWU(splitted[i], "neon", "KDE NeOwOn"); - else KERNEL_TO_UWU(splitted[i], "nixos", "nixOwOs"); - else KERNEL_TO_UWU(splitted[i], "opensuse-leap", "OwOpenSUSE Leap"); - else KERNEL_TO_UWU(splitted[i], "opensuse-tumbleweed", "OwOpenSUSE Tumbleweed"); - else KERNEL_TO_UWU(splitted[i], "pop", "PopOwOS"); - else KERNEL_TO_UWU(splitted[i], "raspbian", "RaspNyan"); - else KERNEL_TO_UWU(splitted[i], "slackware", "Swackwawe"); - else KERNEL_TO_UWU(splitted[i], "solus", "sOwOlus"); - else KERNEL_TO_UWU(splitted[i], "ubuntu", "Uwuntu"); - else KERNEL_TO_UWU(splitted[i], "void", "OwOid"); - else KERNEL_TO_UWU(splitted[i], "xerolinux", "xuwulinux"); - else KERNEL_TO_UWU(splitted[i], "android", "Nyandroid"); // android at the end because it could be not considered as an actual distribution of gnu/linux - - // BSD - else KERNEL_TO_UWU(splitted[i], "freebsd", "FweeBSD"); - else KERNEL_TO_UWU(splitted[i], "openbsd", "OwOpenBSD"); - - // Apple family - else KERNEL_TO_UWU(splitted[i], "macos", "macOwOS"); - else KERNEL_TO_UWU(splitted[i], "ios", "iOwOS"); - - // Windows - else KERNEL_TO_UWU(splitted[i], "windows", "WinyandOwOws"); - - if (i != 0) strcat(kernel, " "); - strcat(kernel, splitted[i]); - } -#undef KERNEL_TO_UWU -} - -void uwu_hw(char* hwname) { -#define HW_TO_UWU(original, uwuified) \ - replace_ignorecase(hwname, original, uwuified); - HW_TO_UWU("lenovo", "LenOwO") - HW_TO_UWU("cpu", "CC\bPUwU"); // for some reasons this caused a segfault, using a \b (backspace) char fixes it - HW_TO_UWU("gpu", "GG\bPUwU") - HW_TO_UWU("graphics", "Gwaphics") - HW_TO_UWU("corporation", "COwOpowation") - HW_TO_UWU("nvidia", "NyaVIDIA") - HW_TO_UWU("mobile", "Mwobile") - HW_TO_UWU("intel", "Inteww") - HW_TO_UWU("radeon", "Radenyan") - HW_TO_UWU("geforce", "GeFOwOce") - HW_TO_UWU("raspberry", "Nyasberry") - HW_TO_UWU("broadcom", "Bwoadcom") - HW_TO_UWU("motorola", "MotOwOwa") - HW_TO_UWU("proliant", "ProLinyant") - HW_TO_UWU("poweredge", "POwOwEdge") - HW_TO_UWU("apple", "Nyaa\bpple") - HW_TO_UWU("electronic", "ElectrOwOnic") -#undef HW_TO_UWU -} - -// get all necessary info -#ifdef _WIN32 -struct info get_info(struct configuration* config_flags) -#else -struct info get_info() -#endif -{ - struct info user_info = {0}; - char buffer[256]; // line buffer - - // get terminal width used to truncate long names -#ifndef _WIN32 - ioctl(STDOUT_FILENO, TIOCGWINSZ, &user_info.win); - user_info.target_width = user_info.win.ws_col - 30; -#else // _WIN32 - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - user_info.ws_col = csbi.srWindow.Right - csbi.srWindow.Left - 29; - user_info.ws_rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; -#endif // _WIN32 - - // os version, cpu and board info -#ifdef __OPENBSD__ - FILE* os_release = popen("echo ID=openbsd", "r"); // os-release does not exist in OpenBSD -#else - FILE* os_release = fopen("/etc/os-release", "r"); // os name file -#endif -#ifndef __BSD__ - FILE* cpuinfo = fopen("/proc/cpuinfo", "r"); // cpu name file for not-freebsd systems -#else - FILE* cpuinfo = popen("sysctl hw.model", "r"); // cpu name command for freebsd -#endif - // trying to get some kind of information about the name of the computer (hopefully a product full name) - FILE* model_fp /* = fopen("/sys/devices/virtual/dmi/id/product_version", "r") */; // trying to get product version - // if (!model_fp) model_fp = fopen("/sys/devices/virtual/dmi/id/product_name", "r"); // trying to get product name - // if (!model_fp) model_fp = fopen("/sys/devices/virtual/dmi/id/board_name", "r"); // trying to get motherboard name - char model_filename[3][256] = {"/sys/devices/virtual/dmi/id/product_version", - "/sys/devices/virtual/dmi/id/product_name", - "/sys/devices/virtual/dmi/id/board_name"}; - - char tmp_model[3][256]; // temporary variable to store the contents of all 3 files - int longest_model = 0, best_len = 0, currentlen = 0; - for (int i = 0; i < 3; i++) { - // read file - model_fp = fopen(model_filename[i], "r"); - if (model_fp) { - fgets(tmp_model[i], 256, model_fp); - tmp_model[i][strlen(tmp_model[i]) - 1] = '\0'; - fclose(model_fp); - } - // choose the file with the longest name - currentlen = strlen(tmp_model[i]); - if (currentlen > best_len) { - best_len = currentlen; - longest_model = i; - } - } - sprintf(user_info.model, "%s", tmp_model[longest_model]); // read model name -#ifdef _WIN32 - // all the previous files obviously did not exist on windows - model_fp = popen("wmic computersystem get model", "r"); - while (fgets(buffer, sizeof(buffer), model_fp)) { - if (strstr(buffer, "Model") != 0) - continue; - else { - sprintf(user_info.model, "%s", buffer); - user_info.model[strlen(user_info.model) - 2] = '\0'; - break; - } - } -#elif defined(__BSD__) || defined(__APPLE__) - #if defined(__BSD__) && !defined(__OPENBSD__) - #define HOSTCTL "hw.hv_vendor" - #elif defined(__APPLE__) - #define HOSTCTL "hw.model" - #elif defined(__OPENBSD__) - #define HOSTCTL "hw.product" - #endif - model_fp = popen("sysctl " HOSTCTL, "r"); - while (fgets(buffer, sizeof(buffer), model_fp)) - if (sscanf(buffer, HOSTCTL -#ifndef __OPENBSD__ - ": " -#else - "=" -#endif - "%[^\n]", user_info.model)) break; -#endif // _WIN32 - if (os_release) { // get normal vars if os_release exists - while (fgets(buffer, sizeof(buffer), os_release) && !(sscanf(buffer, "\nID=\"%s\"", user_info.os_name) || sscanf(buffer, "\nID=%s", user_info.os_name))) - ; - // sometimes for some reason sscanf reads the last '\"' too - int os_name_len = strlen(user_info.os_name); - if (user_info.os_name[os_name_len - 1] == '\"') { - user_info.os_name[os_name_len - 1] = '\0'; - } - /* trying to detect amogos because in its os-release file ID value is just "debian", - will be removed when amogos will have an os-release file with ID=amogos */ - if (strcmp(user_info.os_name, "debian") == 0 || strcmp(user_info.os_name, "raspbian") == 0) { - DIR* amogos_plymouth = opendir("/usr/share/plymouth/themes/amogos"); - if (amogos_plymouth) { - closedir(amogos_plymouth); - sprintf(user_info.os_name, "amogos"); - } - } - /* if (model_fp) { // what the fuck is this? I don't remember writing this code - while (fgets(buffer, sizeof(buffer), model_fp) && !(sscanf(buffer, "%[^\n]", user_info.model))) - ; - char version[32]; - while (fgets(buffer, sizeof(buffer), model_fp)) { - if (sscanf(buffer, "%[^\n]", version)) { - strcat(user_info.model, " "); - strcat(user_info.model, version); - break; - } - } - } */ - - // getting cpu name - while (fgets(buffer, sizeof(buffer), cpuinfo)) { -#ifdef __BSD__ - if (sscanf(buffer, "hw.model" -#ifdef __FREEBSD__ - ": " -#elif defined(__OPENBSD__) - "=" -#endif - "%[^\n]", user_info.cpu_model)) - break; -#else - if (sscanf(buffer, "model name : %[^\n]", user_info.cpu_model)) - break; -#endif // __BSD__ - } - // getting username - char* tmp_user = getenv("USER"); - if (tmp_user == NULL) - sprintf(user_info.user, "%s", ""); - else - sprintf(user_info.user, "%s", tmp_user); - fclose(os_release); - } else { // try for android vars, next for Apple var, or unknown system - // android - DIR* system_app = opendir("/system/app/"); - DIR* system_priv_app = opendir("/system/priv-app/"); - DIR* library = opendir("/Library/"); - if (system_app && system_priv_app) { - closedir(system_app); - closedir(system_priv_app); - sprintf(user_info.os_name, "android"); - // username - FILE* whoami = popen("whoami", "r"); - if (fscanf(whoami, "%s", user_info.user) == 3) - sprintf(user_info.user, "unknown"); - pclose(whoami); - // model name - model_fp = popen("getprop ro.product.model", "r"); - while (fgets(buffer, sizeof(buffer), model_fp) && !sscanf(buffer, "%[^\n]", user_info.model)) - ; -#ifndef __BSD__ - while (fgets(buffer, sizeof(buffer), cpuinfo) && !sscanf(buffer, "Hardware : %[^\n]", user_info.cpu_model)) - ; -#endif - } else if (library) { // Apple - closedir(library); -#ifdef __APPLE__ - sysctlbyname("machdep.cpu.brand_string", &cpu_buffer, &cpu_buffer_len, NULL, 0); // cpu name - #ifndef __IPHONE__ - sprintf(user_info.os_name, "macos"); - #else - sprintf(user_info.os_name, "ios"); - #endif - sprintf(user_info.cpu_model, "%s", cpu_buffer); -#endif - } else - sprintf(user_info.os_name, "unknown"); // if no option before is working, the system is unknown - } -#ifndef __BSD__ - fclose(cpuinfo); -#endif -#ifndef _WIN32 - gethostname(user_info.host, 256); // hostname - char* tmp_shell = getenv("SHELL"); // shell name - if (tmp_shell == NULL) - sprintf(user_info.shell, "%s", ""); - else - sprintf(user_info.shell, "%s", tmp_shell); - #ifdef __linux__ - if (strlen(user_info.shell) > 16) // android shell name was too long - memmove(&user_info.shell, &user_info.shell[27], strlen(user_info.shell)); - #endif -#else // if _WIN32 - // cpu name - cpuinfo = popen("wmic cpu get caption", "r"); - while (fgets(buffer, sizeof(buffer), cpuinfo)) { - if (strstr(buffer, "Caption") != 0) - continue; - else { - sprintf(user_info.cpu_model, "%s", buffer); - user_info.cpu_model[strlen(user_info.cpu_model) - 2] = '\0'; - break; - } - } - // username - FILE* user_host_fp = popen("wmic computersystem get username", "r"); - while (fgets(buffer, sizeof(buffer), user_host_fp)) { - if (strstr(buffer, "UserName") != 0) - continue; - else { - sscanf(buffer, "%[^\\]%s", user_info.host, user_info.user); - memmove(user_info.user, user_info.user + 1, - sizeof(user_info.user) - 1); - break; - } - } - // powershell version - FILE* shell_fp = popen("powershell $PSVersionTable", "r"); - sprintf(user_info.shell, "PowerShell "); - char tmp_shell[64]; - while (fgets(buffer, sizeof(buffer), shell_fp) && sscanf(buffer, "PSVersion %s", tmp_shell) == 0) - ; - strcat(user_info.shell, tmp_shell); -#endif // _WIN32 - truncate_str(user_info.cpu_model, user_info.target_width); - - // system resources -#ifndef _WIN32 - uname(&user_info.sys_var); -#endif // _WIN32 -#ifndef __APPLE__ - #ifndef __BSD__ - #ifndef _WIN32 - sysinfo(&user_info.sys); // somehow this function has to be called again in print_info() - #else - GetSystemInfo(&user_info.sys); - #endif - #endif -#endif - -#ifndef _WIN32 - truncate_str(user_info.sys_var.release, user_info.target_width); - sprintf(user_info.kernel, "%s %s %s", user_info.sys_var.sysname, user_info.sys_var.release, user_info.sys_var.machine); // kernel name - truncate_str(user_info.kernel, user_info.target_width); -#else // _WIN32 - // os name and windows version - sprintf(user_info.os_name, "windows"); - FILE* kernel_fp = popen("wmic computersystem get systemtype", "r"); - while (fgets(buffer, sizeof(buffer), kernel_fp)) { - if (strstr(buffer, "SystemType") != 0) - continue; - else { - sprintf(user_info.kernel, "%s", buffer); - user_info.kernel[strlen(user_info.kernel) - 2] = '\0'; - break; - } - } - if (kernel_fp) pclose(kernel_fp); -#endif // _WIN32 - - // ram -#ifndef __APPLE__ - #ifdef _WIN32 - FILE* mem_used_fp = popen("wmic os get freevirtualmemory", "r"); // free memory - FILE* mem_total_fp = popen("wmic os get totalvirtualmemorysize", "r"); // total memory - char mem_used_ch[2137] = {0}, mem_total_ch[2137] = {0}; - - while (fgets(mem_total_ch, sizeof(mem_total_ch), mem_total_fp) != NULL) { - if (strstr(mem_total_ch, "TotalVirtualMemorySize") != 0) - continue; - else if (strstr(mem_total_ch, " ") == 0) - continue; - else - user_info.ram_total = atoi(mem_total_ch) / 1024; - } - while (fgets(mem_used_ch, sizeof(mem_used_ch), mem_used_fp) != NULL) { - if (strstr(mem_used_ch, "FreeVirtualMemory") != 0) - continue; - else if (strstr(mem_used_ch, " ") == 0) - continue; - else - user_info.ram_used = - user_info.ram_total - (atoi(mem_used_ch) / 1024); - } - pclose(mem_used_fp); - pclose(mem_total_fp); - #else // if not _WIN32 - FILE* meminfo; - - #ifdef __BSD__ - #ifndef __OPENBSD__ - meminfo = popen("LANG=EN_us freecolor -om 2> /dev/null", "r"); // free alternative for freebsd - #else - meminfo = popen("LANG=EN_us vmstat 2> /dev/null | grep -v 'procs' | grep -v 'r' | awk '{print $3 \" / \" $4}'", "r"); // free alternative for openbsd - #endif - #else - // getting memory info from /proc/meminfo: https://github.com/KittyKatt/screenFetch/issues/386#issuecomment-249312716 - meminfo = fopen("/proc/meminfo", "r"); // popen("LANG=EN_us free -m 2> /dev/null", "r"); // get ram info with free - #endif - // brackets are here to restrict the access to this int variables, which are temporary - { - #ifndef __OPENBSD__ - int memtotal = 0, shmem = 0, memfree = 0, buffers = 0, cached = 0, sreclaimable = 0; - #endif - while (fgets(buffer, sizeof(buffer), meminfo)) { - #ifndef __OPENBSD__ - sscanf(buffer, "MemTotal: %d", &memtotal); - sscanf(buffer, "Shmem: %d", &shmem); - sscanf(buffer, "MemFree: %d", &memfree); - sscanf(buffer, "Buffers: %d", &buffers); - sscanf(buffer, "Cached: %d", &cached); - sscanf(buffer, "SReclaimable: %d", &sreclaimable); - #else - sscanf(buffer, "%dM / %dM", &user_info.ram_used, &user_info.ram_total); - #endif - } - #ifndef __OPENBSD__ - user_info.ram_total = memtotal / 1024; - user_info.ram_used = ((memtotal + shmem) - (memfree + buffers + cached + sreclaimable)) / 1024; - #endif - } - - // while (fgets(buffer, sizeof(buffer), meminfo)) // old way to get ram usage that uses the "free" command - // // free command prints like this: "Mem:" total used free shared buff/cache available - // sscanf(buffer, "Mem: %d %d", &user_info.ram_total, &user_info.ram_used); - fclose(meminfo); - #endif -#else // if __APPLE__ - // Used - FILE *mem_wired_fp, *mem_active_fp, *mem_compressed_fp; - mem_wired_fp = popen("vm_stat | awk '/wired/ { printf $4 }' | cut -d '.' -f 1", "r"); - mem_active_fp = popen("vm_stat | awk '/active/ { printf $3 }' | cut -d '.' -f 1", "r"); - mem_compressed_fp = popen("vm_stat | awk '/occupied/ { printf $5 }' | cut -d '.' -f 1", "r"); - char mem_wired_ch[2137], mem_active_ch[2137], mem_compressed_ch[2137]; - while (fgets(mem_wired_ch, sizeof(mem_wired_ch), mem_wired_fp) != NULL) - while (fgets(mem_active_ch, sizeof(mem_active_ch), mem_active_fp) != NULL) - while (fgets(mem_compressed_ch, sizeof(mem_compressed_ch), mem_compressed_fp) != NULL) - ; - - pclose(mem_wired_fp); - pclose(mem_active_fp); - pclose(mem_compressed_fp); - - int mem_wired = atoi(mem_wired_ch); - int mem_active = atoi(mem_active_ch); - int mem_compressed = atoi(mem_compressed_ch); - - // Total - sysctlbyname("hw.memsize", &mem_buffer, &mem_buffer_len, NULL, 0); - user_info.ram_used = ((mem_wired + mem_active + mem_compressed) * 4 / 1024); - user_info.ram_total = mem_buffer / 1024 / 1024; -#endif - - // gpus - int gpuc = 0; // gpu counter -#ifndef _WIN32 - setenv("LANG", "en_US", 1); // force language to english -#endif - FILE* gpu; -#ifndef _WIN32 - gpu = popen("lshw -class display 2> /dev/null", "r"); - - // add all gpus to the array gpu_model - while (fgets(buffer, sizeof(buffer), gpu)) - if (sscanf(buffer, " product: %[^\n]", user_info.gpu_model[gpuc])) - gpuc++; -#endif - - if (strlen(user_info.gpu_model[0]) < 2) { - // get gpus with lspci command - if (strcmp(user_info.os_name, "android") != 0) { -#ifndef __APPLE__ - #ifdef _WIN32 - gpu = popen("wmic PATH Win32_VideoController GET Name", "r"); - #else - gpu = popen("lspci -mm 2> /dev/null | grep \"VGA\" | awk -F '\"' '{print $4 $5 $6}'", "r"); - #endif -#else - gpu = popen("system_profiler SPDisplaysDataType | awk -F ': ' '/Chipset Model: /{ print $2 }'", "r"); -#endif - } else - gpu = popen("getprop ro.hardware.vulkan 2> /dev/null", "r"); // for android - } - - // get all the gpus - while (fgets(buffer, sizeof(buffer), gpu)) { - // windows - if (strstr(buffer, "Name") || (strlen(buffer) == 2)) - continue; - else if (sscanf(buffer, "%[^\n]", user_info.gpu_model[gpuc])) - gpuc++; - } - fclose(gpu); - - // format gpu names - for (int i = 0; i < gpuc; i++) { - remove_brackets(user_info.gpu_model[i]); - truncate_str(user_info.gpu_model[i], user_info.target_width); - } - - // Resolution -#ifndef _WIN32 - FILE* resolution = popen("xwininfo -root 2> /dev/null | grep -E 'Width|Height'", "r"); - while (fgets(buffer, sizeof(buffer), resolution)) { - sscanf(buffer, " Width: %d", &user_info.screen_width); - sscanf(buffer, " Height: %d", &user_info.screen_height); - } -#endif - if (strcmp(user_info.os_name, "windows")) MOVE_CURSOR = "\033[21C"; // to print windows logo on not windows systems - - // package count -#ifdef _WIN32 - user_info.pkgs = pkgman(&user_info, config_flags); -#else // _WIN32 - user_info.pkgs = pkgman(&user_info); -#endif // _WIN32 - - // uwufy info - uwu_kernel(user_info.kernel); - for (int i = 0; user_info.gpu_model[i][0]; i++) uwu_hw(user_info.gpu_model[i]); - uwu_hw(user_info.cpu_model); - uwu_hw(user_info.model); - return user_info; -} - -/* prints distribution list - distributions are listed by distribution branch - to make the output easier to understand by the user.*/ -void list(char* arg) { - printf("%s -d \n" - " Available distributions:\n" - " %sArch linux %sbased:\n" - " %sarch, arcolinux, %sartix, endeavouros %smanjaro, " - "manjaro-arm, %sxerolinux\n\n" - " %sDebian/%sUbuntu %sbased:\n" - " %samogos, debian, %slinuxmint, neon %spop, %sraspbian " - "%subuntu\n\n" - " %sBSD %sbased:\n" - " %sfreebsd, %sopenbsd, %sm%sa%sc%so%ss, %sios\n\n" - " %sOther/spare distributions:\n" - " %salpine, %sfedora, %sgentoo, %sslackware, %ssolus, %svoid, " - "opensuse-leap, android, %sgnu, guix, %swindows, %sunknown\n\n", - arg, BLUE, NORMAL, BLUE, MAGENTA, GREEN, BLUE, // Arch based colors - RED, YELLOW, NORMAL, RED, GREEN, BLUE, RED, YELLOW, // Debian based colors - RED, NORMAL, RED, YELLOW, GREEN, YELLOW, RED, PINK, BLUE, WHITE, // BSD/Apple colors - NORMAL, BLUE, BLUE, PINK, MAGENTA, WHITE, GREEN, YELLOW, BLUE, - WHITE); // Other/spare distributions colors -} - -// prints the usage -void usage(char* arg) { - printf("Usage: %s \n" - " -a, --ascii prints logo as ascii text (default)\n" - " -c --config use custom config path\n" - " -d, --distro lets you choose the logo to print\n" - " -h, --help prints this help page\n" -#ifndef __IPHONE__ - " -i, --image prints logo as image and use a custom image if provided\n" - " %sworks in most terminals\n" -#else - " -i, --image prints logo as image and use a custom image if provided\n" - " %sdisabled under iOS\n" -#endif - " read README.md for more info%s\n" - " -l, --list lists all supported distributions\n" - " -v, --version prints the current uwufetch version\n" - " -w, --write-cache writes to the cache file (~/.cache/uwufetch.cache)\n" - " using the cache set $UWUFETCH_CACHE_ENABLED to TRUE, true or 1\n", - arg, -#ifndef __IPHONE__ - BLUE, -#else - RED, -#endif - NORMAL); -} - -// the main function is on the bottom of the file to avoid double function declarations -int main(int argc, char* argv[]) { - char* cache_env = getenv("UWUFETCH_CACHE_ENABLED"); // getting cache env variable - struct configuration config_flags; - struct info user_info = {0}; - if (cache_env != NULL) { // if cache env variable is set, read itz value - int cache_enabled = 0; - char buffer[128]; - - sscanf(cache_env, "%4[TRUEtrue1]", buffer); - cache_enabled = (strcmp(buffer, "true") == 0 || strcmp(buffer, "TRUE") == 0 || strcmp(buffer, "1") == 0); // enable the cache if necessary - if (cache_enabled) { - // if no cache file found write to it - if (!read_cache(&user_info)) { -#ifdef _WIN32 - user_info = get_info(&config_flags); -#else - user_info = get_info(); -#endif - write_cache(&user_info); - } - config_flags = parse_config(&user_info); // reading the config - if (print_cache(&config_flags, &user_info) < 7) - printf("\033[3B"); - return 0; - } - } -#ifdef _WIN32 - // packages disabled by default because chocolatey is too slow - config_flags.show_pkgs = 0; -#endif - - int opt = 0; - static struct option long_options[] = - {{"ascii", no_argument, NULL, 'a'}, - {"config", required_argument, NULL, 'c'}, - // {"cache", no_argument, NULL, 'C'}, // using an environment variable is not a good idea, maybe some time in the future, uwufetch will use a command line option - {"distro", required_argument, NULL, 'd'}, - {"help", no_argument, NULL, 'h'}, - {"image", optional_argument, NULL, 'i'}, - {"list", no_argument, NULL, 'l'}, - {"version", no_argument, NULL, 'v'}, - {"write-cache", no_argument, NULL, 'w'}, - {NULL, 0, NULL, 0}}; - -#ifdef _WIN32 - user_info = get_info(&config_flags); // get the info to modify it with cmdline options -#else - user_info = get_info(); -#endif - config_flags = parse_config(&user_info); // same as user_info - - // reading cmdline options - while ((opt = getopt_long(argc, argv, "ac:d:hi::lvw", long_options, NULL)) != -1) { - switch (opt) { - case 'a': // set ascii logo as output - config_flags.ascii_image_flag = 0; - break; - case 'c': // set the config directory - user_info.config_directory = optarg; - break; - case 'd': // set the distribution name - if (optarg) sprintf(user_info.os_name, "%s", optarg); - break; - case 'h': - usage(argv[0]); - return 0; - case 'i': // set ascii logo as output - config_flags.ascii_image_flag = 1; - if (!optarg && argv[optind] != NULL && argv[optind][0] != '-') // set default image name - sprintf(user_info.image_name, "%s", argv[optind++]); - else if (optarg) // set user-defined image name - sprintf(user_info.image_name, "%s", optarg); - break; - case 'l': - list(argv[0]); - return 0; - case 'v': - printf("UwUfetch version %s\n", UWUFETCH_VERSION); - return 0; - case 'w': - write_cache(&user_info); - if (print_cache(&config_flags, &user_info) < 7) - printf("\033[3B"); - return 0; - default: - break; - } - } - if ((argc == 1 && config_flags.ascii_image_flag == 0) || (argc > 1 && config_flags.ascii_image_flag == 0)) - print_ascii(&user_info); - else if (config_flags.ascii_image_flag == 1) - print_image(&user_info); - - // if the number of printed lines is too small, move the cursor down - if (print_info(&config_flags, &user_info) < 7) - printf("\033[3B"); - return 0; -}