2021-03-09 06:00:41 +01:00
/*
* 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 < https : //www.gnu.org/licenses/>.
*/
2021-09-10 00:51:37 +02:00
# define _GNU_SOURCE // for strcasestr
2021-09-07 06:59:34 +02:00
2021-11-06 00:34:53 +01:00
# ifdef __APPLE__
2021-11-28 15:57:20 +01:00
# include <TargetConditionals.h> // for checking iOS
2021-11-06 00:34:53 +01:00
# endif
2021-03-07 22:04:05 +01:00
# include <dirent.h>
2021-11-28 15:57:20 +01:00
# include <getopt.h>
2021-03-05 17:22:48 +01:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
2021-07-24 12:27:38 +02:00
# if defined(__APPLE__) || defined(__FREEBSD__)
2021-11-28 15:57:20 +01:00
# include <sys/sysctl.h>
# include <time.h>
2021-11-01 16:48:54 +01:00
# else // defined(__APPLE__) || defined(__FREEBSD__)
2021-11-28 15:57:20 +01:00
# ifdef __FREEBSD__
# else // defined(__FREEBSD__) || defined(_WIN32)
# ifndef _WIN32
# include <sys/sysinfo.h>
# else // _WIN32
# include <sysinfoapi.h>
# endif // _WIN32
# endif // defined(__FREEBSD__) || defined(_WIN32)
# endif // defined(__APPLE__) || defined(__FREEBSD__)
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
2021-11-28 15:57:20 +01:00
# include <sys/ioctl.h>
# include <sys/utsname.h>
2021-11-26 18:03:14 +01:00
# else // _WIN32
2021-11-28 15:57:20 +01:00
# include <windows.h>
2021-11-01 16:48:54 +01:00
CONSOLE_SCREEN_BUFFER_INFO csbi ;
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-03-06 21:17:29 +01:00
2021-03-05 17:22:48 +01:00
// COLORS
2021-04-15 09:28:57 +02:00
# define NORMAL "\x1b[0m"
# define BOLD "\x1b[1m"
# define BLACK "\x1b[30m"
# define RED "\x1b[31m"
# define GREEN "\x1b[32m"
2021-11-01 16:48:54 +01:00
# define SPRING_GREEN "\x1b[38;5;120m"
2021-04-15 09:28:57 +02:00
# 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"
2021-11-01 16:48:54 +01:00
2021-11-26 18:03:14 +01:00
# ifdef _WIN32
2021-12-23 13:27:30 +01:00
# define BLOCK_CHAR "\xdb" // block char for colors
# else // _WIN32
2021-11-28 15:57:20 +01:00
# define BLOCK_CHAR "\u2587"
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-04-15 22:59:43 +02:00
# ifdef __APPLE__
2021-11-28 15:57:20 +01:00
// buffers where data fetched from sysctl are stored
// CPU
# define CPUBUFFERLEN 128
2021-04-15 22:59:43 +02:00
2021-04-16 10:48:39 +02:00
char cpu_buffer [ CPUBUFFERLEN ] ;
size_t cpu_buffer_len = CPUBUFFERLEN ;
2021-04-15 22:59:43 +02:00
2021-04-16 10:48:39 +02:00
// Installed RAM
2021-11-28 15:57:20 +01:00
int64_t mem_buffer = 0 ;
2021-04-16 10:48:39 +02:00
size_t mem_buffer_len = sizeof ( mem_buffer ) ;
2021-04-15 22:59:43 +02:00
2021-04-16 10:48:39 +02:00
// uptime
struct timeval time_buffer ;
size_t time_buffer_len = sizeof ( time_buffer ) ;
2021-11-01 16:48:54 +01:00
# endif // __APPLE__
2021-04-15 09:28:57 +02:00
2021-11-28 15:57:20 +01:00
struct package_manager {
2021-04-15 09:28:57 +02:00
char command_string [ 128 ] ; // command to get number of packages installed
char pkgman_name [ 16 ] ; // name of the package manager
2021-04-06 15:56:09 +02:00
} ;
2021-05-03 03:46:55 +02:00
2021-12-23 13:27:30 +01:00
// all configuration flags available
2021-11-28 15:57:20 +01:00
struct configuration {
2021-12-23 13:27:30 +01:00
int ascii_image_flag , // when (0) ascii is printed, when (1) image is printed
show_user_info , // all the following flags are 1 (true) by default
show_os ,
show_host ,
show_kernel ,
show_cpu ,
show_gpu ,
show_ram ,
show_resolution ,
show_shell ,
show_pkgs ,
show_uptime ,
2021-11-26 18:03:14 +01:00
show_colors ;
} ;
2021-03-18 21:54:29 +01:00
2021-12-23 13:27:30 +01:00
// info that will be printed with the logo
2021-11-28 15:57:20 +01:00
struct info {
2021-12-23 13:27:30 +01:00
char user [ 128 ] , // username
host [ 256 ] , // hostname (computer name)
shell [ 64 ] , // shell name
host_model [ 256 ] , // motherboard name
host_model_version [ 256 ] , // alternative to motherboard name if it doesn't exist
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
2021-12-23 14:52:55 +01:00
int target_width , // for the truncate_str function
2021-12-23 13:27:30 +01:00
screen_width ,
screen_height ,
ram_total ,
ram_used ,
pkgs ; // full package count
2021-11-26 18:03:14 +01:00
long uptime ;
# ifndef _WIN32
struct utsname sys_var ;
# endif // _WIN32
# ifndef __APPLE__
2021-11-28 15:57:20 +01:00
# ifdef __linux__
2021-11-26 18:03:14 +01:00
struct sysinfo sys ;
2021-11-28 15:57:20 +01:00
# else // __linux__
# ifdef _WIN32
2021-11-26 18:03:14 +01:00
struct _SYSTEM_INFO sys ;
2021-11-28 15:57:20 +01:00
# endif // _WIN32
# endif // __linux__
# endif // __APPLE__
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
struct winsize win ;
# else // _WIN32
int ws_col , ws_rows ;
# endif // _WIN32
} ;
2021-11-01 16:48:54 +01:00
2021-12-23 13:27:30 +01:00
char * MOVE_CURSOR = " \033 [18C " ; // moves the cursor after printing the image or the ascii logo
2021-03-05 17:22:48 +01:00
2021-12-23 14:52:55 +01:00
// reads the config file
2021-12-05 13:34:56 +01:00
struct configuration parse_config ( struct info * user_info ) {
2021-12-23 13:27:30 +01:00
char buffer [ 256 ] ; // buffer for the current line
struct configuration config_flags = { 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ; // enabling all flags by default
2021-04-15 09:28:57 +02:00
2021-12-23 13:27:30 +01:00
FILE * config = NULL ; // config file pointer
if ( user_info - > config_directory = = NULL ) { // if config directory is not set, try to open the default
2021-11-28 15:57:20 +01:00
if ( getenv ( " HOME " ) ! = NULL ) {
2021-10-14 13:23:54 +02:00
char homedir [ 512 ] ;
2021-10-08 23:11:27 +02:00
sprintf ( homedir , " %s/.config/uwufetch/config " , getenv ( " HOME " ) ) ;
2021-11-01 16:55:33 +01:00
config = fopen ( homedir , " r " ) ;
2021-10-08 23:11:27 +02:00
}
2021-11-28 15:57:20 +01:00
} else
2021-11-26 18:03:14 +01:00
config = fopen ( user_info - > config_directory , " r " ) ;
2021-12-23 13:27:30 +01:00
if ( config = = NULL ) return config_flags ; // if config file does not exist, return the defaults
2021-04-19 00:01:29 +02:00
2021-12-23 13:27:30 +01:00
// reading the config file
while ( fgets ( buffer , sizeof ( buffer ) , config ) ) {
sscanf ( buffer , " distro=%s " , user_info - > os_name ) ;
if ( sscanf ( buffer , " ascii=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . ascii_image_flag = ! strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
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
2021-04-23 18:02:05 +02:00
char temp [ 128 ] = " /home/ " ;
2021-11-26 18:03:14 +01:00
strcat ( temp , user_info - > user ) ;
strcat ( temp , user_info - > image_name ) ;
sprintf ( user_info - > image_name , " %s " , temp ) ;
2021-04-23 18:02:05 +02:00
}
2021-12-23 13:27:30 +01:00
config_flags . ascii_image_flag = 1 ; // enable the image flag
2021-04-23 18:02:05 +02:00
}
2021-12-23 13:27:30 +01:00
// reading other values
if ( sscanf ( buffer , " user=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_user_info = ! strcmp ( buffer , " true " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " os=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_os = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " host=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_host = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " kernel=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_kernel = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " cpu=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_cpu = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " gpu=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_gpu = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " ram=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_ram = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " resolution=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_resolution = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " shell=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_shell = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " pkgs=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_pkgs = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " uptime=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_uptime = strcmp ( buffer , " false " ) ;
2021-12-23 13:27:30 +01:00
if ( sscanf ( buffer , " colors=%[truefalse] " , buffer ) )
2021-11-26 18:03:14 +01:00
config_flags . show_colors = strcmp ( buffer , " false " ) ;
2021-04-23 18:02:05 +02:00
}
fclose ( config ) ;
2021-11-26 18:03:14 +01:00
return config_flags ;
2021-04-14 00:21:29 +02:00
}
2021-12-23 14:52:55 +01:00
// gets the installed package count and package managers name
2021-11-26 18:03:14 +01:00
# ifdef _WIN32
2021-12-05 13:34:56 +01:00
int pkgman ( struct info * user_info , struct configuration * config_flags )
2021-11-26 18:03:14 +01:00
# else // _WIN32
2021-12-05 13:34:56 +01:00
int pkgman ( struct info * user_info )
2021-11-26 18:03:14 +01:00
# endif
2021-04-15 09:28:57 +02:00
{ // this is just a function that returns the total of installed packages
2021-04-07 14:13:15 +02:00
int total = 0 ;
2021-12-18 21:38:58 +01:00
# ifndef __APPLE__
2021-12-23 13:27:30 +01:00
// this function is not used on mac os because it causes lots of problems
2021-11-28 15:57:20 +01:00
# ifndef _WIN32
2021-12-23 13:27:30 +01:00
// 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) " } ,
{ " 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) " } ,
{ " 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
2021-04-07 14:13:15 +02:00
fclose ( fp ) ;
2021-12-23 14:52:55 +01:00
// adding a package manager with its package count to user_info->pkgman_name
2021-04-07 14:13:15 +02:00
total + = pkg_count ;
2021-11-28 15:57:20 +01:00
if ( pkg_count > 0 ) {
2021-12-23 13:27:30 +01:00
if ( comma_separator + + ) strcat ( user_info - > pkgman_name , " , " ) ;
2021-04-27 11:07:58 +02:00
char spkg_count [ 16 ] ;
2021-10-14 13:23:54 +02:00
sprintf ( spkg_count , " %u " , pkg_count ) ;
2021-11-26 18:03:14 +01:00
strcat ( user_info - > pkgman_name , spkg_count ) ;
strcat ( user_info - > pkgman_name , " " ) ;
2021-12-23 13:27:30 +01:00
strcat ( user_info - > pkgman_name , current - > pkgman_name ) ;
2021-04-27 11:07:58 +02:00
}
2021-04-07 14:13:15 +02:00
}
2021-11-28 15:57:20 +01:00
# else // _WIN32
2021-12-23 14:52:55 +01:00
// chocolatey for windows
2021-11-28 15:57:20 +01:00
if ( config_flags - > show_pkgs ) {
2021-12-05 13:34:56 +01:00
FILE * fp = popen ( " choco list -l --no-color 2> nul " , " r " ) ;
2021-11-01 16:48:54 +01:00
unsigned int pkg_count ;
char buffer [ 7562 ] = { 0 } ;
2021-11-28 15:57:20 +01:00
while ( fgets ( buffer , sizeof ( buffer ) , fp ) ) {
2021-11-01 16:48:54 +01:00
sscanf ( buffer , " %u packages installed. " , & pkg_count ) ;
}
2021-11-28 15:57:20 +01:00
if ( fp ) pclose ( fp ) ;
2021-11-01 16:48:54 +01:00
total = pkg_count ;
char spkg_count [ 16 ] ;
sprintf ( spkg_count , " %u " , pkg_count ) ;
2021-11-26 18:03:14 +01:00
strcat ( user_info - > pkgman_name , spkg_count ) ;
strcat ( user_info - > pkgman_name , " " ) ;
strcat ( user_info - > pkgman_name , " (chocolatey) " ) ;
2021-11-01 16:48:54 +01:00
}
2021-11-28 15:57:20 +01:00
# endif // _WIN32
2021-11-01 16:48:54 +01:00
2021-05-31 01:04:32 +02:00
# endif
2021-04-07 14:13:15 +02:00
return total ;
2021-03-05 17:22:48 +01:00
}
2021-03-06 21:17:29 +01:00
2021-04-15 22:59:43 +02:00
# ifdef __APPLE__
2021-12-23 14:52:55 +01:00
// gets the uptime for mac os
2021-11-28 15:57:20 +01:00
int uptime_apple ( ) {
2021-04-16 10:48:39 +02:00
int mib [ 2 ] = { CTL_KERN , KERN_BOOTTIME } ;
sysctl ( mib , 2 , & time_buffer , & time_buffer_len , NULL , 0 ) ;
2021-04-15 22:59:43 +02:00
2021-04-16 10:48:39 +02:00
time_t bsec = time_buffer . tv_sec ;
time_t csec = time ( NULL ) ;
2021-04-15 22:59:43 +02:00
2021-04-16 10:48:39 +02:00
return difftime ( csec , bsec ) ;
2021-04-15 22:59:43 +02:00
}
# endif
2021-07-24 12:27:38 +02:00
# ifdef __FREEBSD__
2021-12-23 14:52:55 +01:00
// gets the uptime for freebsd
int uptime_freebsd ( ) { // this code is from coreutils uptime: https://github.com/coreutils/coreutils/blob/master/src/uptime.c
2021-11-28 15:57:20 +01:00
int boot_time = 0 ;
2021-09-10 00:51:37 +02:00
static int request [ 2 ] = { CTL_KERN , KERN_BOOTTIME } ;
2021-07-24 12:27:38 +02:00
struct timeval result ;
size_t result_len = sizeof result ;
2021-09-10 00:51:37 +02:00
if ( sysctl ( request , 2 , & result , & result_len , NULL , 0 ) > = 0 )
2021-07-24 12:27:38 +02:00
boot_time = result . tv_sec ;
2021-09-10 00:51:37 +02:00
int time_now = time ( NULL ) ;
2021-07-24 12:27:38 +02:00
return time_now - boot_time ;
}
# endif
2021-12-23 14:52:55 +01:00
// prints logo (as an image) of the given system.
void print_image ( struct info * user_info ) {
2021-12-23 13:27:30 +01:00
# ifndef __IPHONE__
char command [ 256 ] ;
if ( strlen ( user_info - > image_name ) > 1 )
2021-12-23 14:52:55 +01:00
sprintf ( command , " viu -t -w 18 -h 8 %s 2> /dev/null " , user_info - > image_name ) ; // creating the command to show the image
2021-12-23 13:27:30 +01:00
else {
if ( strcmp ( user_info - > os_name , " android " ) = = 0 )
2021-12-23 14:52:55 +01:00
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
2021-12-23 13:27:30 +01:00
else
2021-12-23 14:52:55 +01:00
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
2021-12-23 13:27:30 +01:00
}
printf ( " \n " ) ;
2021-12-23 14:52:55 +01:00
if ( system ( command ) ! = 0 ) // if viu is not installed or the image is missing
2021-12-23 13:27:30 +01:00
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
}
2021-12-23 14:52:55 +01:00
// uwufies distro name
void uwu_name ( struct configuration * config_flags , struct info * user_info ) {
2021-12-23 13:27:30 +01:00
# 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 " ) ;
2021-12-23 14:52:55 +01:00
else STRING_TO_UWU ( " android " , " Nyandroid " ) ; // android at the end because it could be not considered as an actual distribution of gnu/linux
2021-12-23 13:27:30 +01:00
// BSD
else STRING_TO_UWU ( " freebsd " , " FweeBSD " ) ;
else STRING_TO_UWU ( " openbsd " , " OwOpenBSD " ) ;
2021-12-23 14:52:55 +01:00
// Apple family
2021-12-23 13:27:30 +01:00
else STRING_TO_UWU ( " macos " , " macOwOS " ) ;
else STRING_TO_UWU ( " ios " , " iOwOS " ) ;
// Windows
else STRING_TO_UWU ( " windows " , " WinyandOwOws " ) ;
else {
2021-12-23 14:52:55 +01:00
sprintf ( user_info - > os_name , " %s " , " unknown " ) ; // replacing the original os name with the uwufied version
2021-12-23 13:27:30 +01:00
if ( config_flags - > ascii_image_flag = = 1 ) {
print_image ( user_info ) ;
printf ( " \n " ) ;
}
}
# undef STRING_TO_UWU
}
2021-12-23 14:52:55 +01:00
// prints all the collected info
2021-12-05 13:34:56 +01:00
void print_info ( struct configuration * config_flags , struct info * user_info ) {
2021-11-26 18:03:14 +01:00
# ifdef _WIN32
2021-12-23 14:52:55 +01:00
// prints without overflowing the terminal width
2021-11-28 15:57:20 +01:00
# define responsively_printf(buf, format, ...) \
{ \
sprintf ( buf , format , __VA_ARGS__ ) ; \
printf ( " %.*s \n " , user_info - > ws_col - 1 , buf ) ; \
}
2021-11-26 18:03:14 +01:00
# else // _WIN32
2021-12-23 14:52:55 +01:00
// prints without overflowing the terminal width
2021-11-28 15:57:20 +01:00
# define responsively_printf(buf, format, ...) \
{ \
sprintf ( buf , format , __VA_ARGS__ ) ; \
printf ( " %.*s \n " , user_info - > win . ws_col - 1 , buf ) ; \
}
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-11-01 16:48:54 +01:00
char print_buf [ 1024 ] ; // for responsively print
2021-11-01 15:15:05 +01:00
2021-04-07 14:13:15 +02:00
// print collected info - from host to cpu info
2021-04-14 12:33:05 +02:00
printf ( " \033 [9A " ) ; // to align info text
2021-11-26 18:03:14 +01:00
if ( config_flags - > show_user_info )
2021-12-23 13:27:30 +01:00
responsively_printf ( print_buf , " %s%s%s%s@%s " , MOVE_CURSOR ,
2021-11-28 15:57:20 +01:00
NORMAL , BOLD , user_info - > user , user_info - > host ) ;
2021-11-26 18:03:14 +01:00
uwu_name ( config_flags , user_info ) ;
if ( config_flags - > show_os )
2021-11-28 15:57:20 +01:00
responsively_printf ( print_buf , " %s%s%sOWOS %s%s " ,
2021-12-23 13:27:30 +01:00
MOVE_CURSOR , NORMAL , BOLD , NORMAL ,
user_info - > os_name ) ;
2021-11-26 18:03:14 +01:00
if ( config_flags - > show_host )
2021-12-18 23:24:58 +01:00
responsively_printf ( print_buf , " %s%s%sMOWODEL %s%s " ,
2021-12-23 13:27:30 +01:00
MOVE_CURSOR , NORMAL , BOLD , NORMAL ,
2021-11-28 15:57:20 +01:00
user_info - > host_model ) ;
2021-11-26 18:03:14 +01:00
if ( config_flags - > show_kernel )
2021-11-28 15:57:20 +01:00
responsively_printf ( print_buf , " %s%s%sKEWNEL %s%s " ,
2021-12-23 13:27:30 +01:00
MOVE_CURSOR , NORMAL , BOLD , NORMAL ,
2021-11-28 15:57:20 +01:00
user_info - > kernel ) ;
2021-11-26 18:03:14 +01:00
if ( config_flags - > show_cpu )
2021-11-28 15:57:20 +01:00
responsively_printf ( print_buf , " %s%s%sCPUWU %s%s " ,
2021-12-23 13:27:30 +01:00
MOVE_CURSOR , NORMAL , BOLD , NORMAL ,
2021-11-28 15:57:20 +01:00
user_info - > cpu_model ) ;
2021-03-18 22:53:32 +01:00
// print the gpus
2021-11-26 18:03:14 +01:00
if ( config_flags - > show_gpu )
for ( int i = 0 ; user_info - > gpu_model [ i ] [ 0 ] ; i + + )
2021-12-23 14:52:55 +01:00
responsively_printf ( print_buf , " %s%s%sGPUWU %s%s " , MOVE_CURSOR , NORMAL , BOLD , NORMAL , user_info - > gpu_model [ i ] ) ;
2021-03-18 21:54:29 +01:00
2021-12-23 14:52:55 +01:00
if ( config_flags - > show_ram ) // print ram
responsively_printf ( print_buf , " %s%s%sWAM %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
2021-11-26 18:03:14 +01:00
if ( user_info - > screen_width ! = 0 | | user_info - > screen_height ! = 0 )
2021-12-23 14:52:55 +01:00
responsively_printf ( print_buf , " %s%s%sRESOWUTION%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 [34mw w \x1b [0m \x1b [1mPKGS \x1b [0m \" $1 \" (brew) \" }' " ) ;
2021-05-31 01:04:32 +02:00
# else
2021-12-23 14:52:55 +01:00
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 ) ;
2021-05-31 01:04:32 +02:00
# endif
2021-12-23 14:52:55 +01:00
if ( config_flags - > show_uptime ) { // print uptime
2021-11-28 15:57:20 +01:00
if ( user_info - > uptime = = 0 ) {
2021-10-08 23:11:27 +02:00
2021-04-18 23:51:32 +02:00
# ifdef __APPLE__
2021-11-26 18:03:14 +01:00
user_info - > uptime = uptime_apple ( ) ;
2021-04-18 23:51:32 +02:00
# else
2021-11-28 15:57:20 +01:00
# ifdef __FREEBSD__
2021-11-26 18:03:14 +01:00
user_info - > uptime = uptime_freebsd ( ) ;
2021-11-28 15:57:20 +01:00
# else
# ifdef _WIN32
2021-11-26 18:03:14 +01:00
user_info - > uptime = GetTickCount ( ) / 1000 ;
2021-11-28 15:57:20 +01:00
# else // _WIN32
2021-11-26 18:03:14 +01:00
user_info - > uptime = user_info - > sys . uptime ;
2021-11-28 15:57:20 +01:00
# endif // _WIN32
# endif
2021-04-18 23:51:32 +02:00
# endif
2021-10-08 23:11:27 +02:00
}
2021-12-23 14:52:55 +01:00
switch ( user_info - > uptime ) { // formatting the uptime which is store in seconds
2021-07-22 18:39:34 +02:00
case 0 . . . 3599 :
2021-12-23 14:52:55 +01:00
responsively_printf ( print_buf , " %s%s%sUWUPTIME %s%lim " , MOVE_CURSOR , NORMAL , BOLD , NORMAL , user_info - > uptime / 60 % 60 ) ;
2021-07-22 18:39:34 +02:00
break ;
case 3600 . . . 86399 :
2021-12-23 14:52:55 +01:00
responsively_printf ( print_buf , " %s%s%sUWUPTIME %s%lih, %lim " , MOVE_CURSOR , NORMAL , BOLD , NORMAL , user_info - > uptime / 3600 , user_info - > uptime / 60 % 60 ) ;
2021-07-22 18:39:34 +02:00
break ;
default :
2021-12-23 14:52:55 +01:00
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 ) ;
2021-06-23 21:46:22 +02:00
}
2021-04-18 23:51:32 +02:00
}
2021-12-23 14:52:55 +01:00
if ( config_flags - > show_colors ) // print colors
2021-11-01 16:48:54 +01:00
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 " ,
2021-12-23 13:27:30 +01:00
MOVE_CURSOR , BOLD , BLACK , BLOCK_CHAR , BLOCK_CHAR , RED ,
2021-11-28 15:57:20 +01:00
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 ) ;
2021-03-06 21:17:29 +01:00
}
2021-12-23 14:52:55 +01:00
// writes cache to cache file
2021-12-05 13:34:56 +01:00
void write_cache ( struct info * user_info ) {
2021-10-08 23:11:27 +02:00
char cache_file [ 512 ] ;
2021-12-23 14:52:55 +01:00
sprintf ( cache_file , " %s/.cache/uwufetch.cache " , getenv ( " HOME " ) ) ; // default cache file location
2021-12-05 13:34:56 +01:00
FILE * cache_fp = fopen ( cache_file , " w " ) ;
2021-12-23 14:52:55 +01:00
if ( cache_fp = = NULL ) {
fprintf ( stderr , " Failed to write to %s! " , cache_file ) ;
return ;
}
// writing all info to the cache file
2021-10-08 23:11:27 +02:00
# ifdef __APPLE__
2021-12-05 13:34:56 +01:00
user_info - > uptime = uptime_apple ( ) ;
2021-10-08 23:11:27 +02:00
# else
2021-11-28 15:57:20 +01:00
# ifdef __FREEBSD__
2021-10-08 23:11:27 +02:00
uptime = uptime_freebsd ( ) ;
2021-11-28 15:57:20 +01:00
# else
# ifndef _WIN32
2021-11-26 18:03:14 +01:00
user_info - > uptime = user_info - > sys . uptime ;
2021-11-28 15:57:20 +01:00
# endif // _WIN32
# endif
2021-10-08 23:11:27 +02:00
# endif
2021-12-23 14:52:55 +01:00
fprintf ( // writing most of the values to config file
2021-11-28 15:57:20 +01:00
cache_fp ,
" user=%s \n host=%s \n version_name=%s \n host_model=%s \n kernel=%s \n cpu=% "
" s \n screen_width=%d \n screen_height=%d \n shell=%s \n pkgs=%d \n pkgman_name=% "
" s \n " ,
2021-12-23 13:27:30 +01:00
user_info - > user , user_info - > host , user_info - > os_name ,
2021-11-28 15:57:20 +01:00
user_info - > host_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 ) ;
2021-10-08 23:11:27 +02:00
2021-12-23 14:52:55 +01:00
for ( int i = 0 ; user_info - > gpu_model [ i ] [ 0 ] ; i + + ) // writing gpu names to file
2021-11-26 18:03:14 +01:00
fprintf ( cache_fp , " gpu=%s \n " , user_info - > gpu_model [ i ] ) ;
2021-10-08 23:11:27 +02:00
# ifdef __APPLE__
/* char brew_command[2048];
2021-11-28 15:57:20 +01:00
sprintf ( brew_command , " ls $(brew --cellar) | wc -l | awk -F' ' '{print \"
\ x1b [ 34 mw w \ x1b [ 0 m \ x1b [ 1 mPKGS \ x1b [ 0 m \ " $1 \" (brew) \" }'
> % s " , cache_file); system(brew_command); */
2021-10-08 23:11:27 +02:00
# endif
fclose ( cache_fp ) ;
2021-10-09 00:19:16 +02:00
return ;
2021-10-08 23:11:27 +02:00
}
2021-12-23 14:52:55 +01:00
// reads cache file if it exists
2021-12-05 13:34:56 +01:00
int read_cache ( struct info * user_info ) {
2021-10-08 23:11:27 +02:00
char cache_file [ 512 ] ;
2021-12-23 14:52:55 +01:00
sprintf ( cache_file , " %s/.cache/uwufetch.cache " , getenv ( " HOME " ) ) ; // cache file location
2021-12-05 13:34:56 +01:00
FILE * cache_fp = fopen ( cache_file , " r " ) ;
2021-11-28 15:57:20 +01:00
if ( cache_fp = = NULL ) return 0 ;
2021-12-23 14:52:55 +01:00
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 - > host_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 ) ;
2021-10-08 23:11:27 +02:00
}
fclose ( cache_fp ) ;
2021-10-11 00:15:46 +02:00
return 1 ;
2021-10-09 00:19:16 +02:00
}
2021-12-23 13:27:30 +01:00
/*
2021-12-23 14:52:55 +01:00
This replaces all terms in a string with another term .
2021-12-23 13:27:30 +01:00
replace ( " Hello World! " , " World " , " everyone " )
2021-12-23 14:52:55 +01:00
This returns " Hello everyone! " .
2021-12-23 13:27:30 +01:00
*/
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 ;
2021-12-23 14:52:55 +01:00
sprintf ( buffer + ( ch - original ) , " %s%s " , replacer , ch + strlen ( search ) ) ;
original [ 0 ] = 0 ;
strcpy ( original , buffer ) ;
}
}
2021-10-09 00:19:16 +02:00
2021-12-23 14:52:55 +01:00
/*
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 ) ) ;
2021-12-23 13:27:30 +01:00
original [ 0 ] = 0 ;
strcpy ( original , buffer ) ;
2021-11-01 16:48:54 +01:00
}
2021-12-23 13:27:30 +01:00
}
2021-11-26 18:03:14 +01:00
2021-12-23 14:52:55 +01:00
// prints logo (as ascii art) of the given system.
void print_ascii ( struct info * user_info ) {
2021-12-23 13:27:30 +01:00
printf ( " \n " ) ;
FILE * file ;
char ascii_file [ 1024 ] ;
2021-12-23 14:52:55 +01:00
// First tries to get ascii art file from local directory. Useful for debugging
2021-12-23 13:27:30 +01:00
sprintf ( ascii_file , " ./res/ascii/%s.txt " , user_info - > os_name ) ;
file = fopen ( ascii_file , " r " ) ;
2021-12-23 14:52:55 +01:00
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
sprintf ( ascii_file , " /usr/lib/uwufetch/ascii/%s.txt " , user_info - > os_name ) ;
2021-12-23 13:27:30 +01:00
file = fopen ( ascii_file , " r " ) ;
if ( ! file ) {
// Prevent infinite loops
if ( strcmp ( user_info - > os_name , " unknown " ) = = 0 ) {
printf ( " No \n unknown \n ascii \n file \n \n \n \n " ) ;
return ;
}
2021-12-23 14:52:55 +01:00
sprintf ( user_info - > os_name , " unknown " ) ; // current os is not supported
2021-12-23 13:27:30 +01:00
return print_ascii ( user_info ) ;
}
}
2021-12-23 14:52:55 +01:00
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
2021-12-23 13:27:30 +01:00
}
2021-12-23 14:52:55 +01:00
// Always set color to NORMAL, so there's no need to do this in every ascii file.
2021-12-23 13:27:30 +01:00
printf ( NORMAL ) ;
fclose ( file ) ;
}
2021-12-23 14:52:55 +01:00
// prints the info after reading the cache file
2021-12-23 13:27:30 +01:00
void print_cache ( struct configuration * config_flags , struct info * user_info ) {
# ifndef __APPLE__
# ifndef _WIN32
sysinfo ( & user_info - > sys ) ; // to get uptime
2021-12-23 14:52:55 +01:00
# endif
2021-12-23 13:27:30 +01:00
FILE * meminfo ;
# ifdef __FREEBSD__
2021-12-23 14:52:55 +01:00
meminfo = popen ( " LANG=EN_us freecolor -om 2> /dev/null " , " r " ) ; // free alternative
# else
meminfo = popen ( " LANG=EN_us free -m 2> /dev/null " , " r " ) ; // using free to get
# endif
2021-12-23 13:27:30 +01:00
char line [ 256 ] ;
2021-12-23 14:52:55 +01:00
while ( fgets ( line , sizeof ( line ) , meminfo ) ) // reading free output
// free command prints like this: "Mem:" total used free shared buff/cache available
2021-12-23 13:27:30 +01:00
sscanf ( line , " Mem: %d %d " , & user_info - > ram_total , & user_info - > ram_used ) ;
fclose ( meminfo ) ;
# elif defined(_WIN32)
FILE * mem_used_fp ;
2021-12-23 14:52:55 +01:00
mem_used_fp = popen ( " wmic OS GET FreePhysicalMemory " , " r " ) ; // free does not exist for windows
2021-12-23 13:27:30 +01:00
char mem_used_ch [ 2137 ] ;
printf ( " \n \n \n \\ \n " ) ;
2021-12-23 14:52:55 +01:00
while ( fgets ( mem_used_ch , sizeof ( mem_used_ch ) , mem_used_fp ) ! = NULL ) printf ( " %s \n " , mem_used_ch ) ;
2021-12-23 13:27:30 +01:00
pclose ( mem_used_fp ) ;
int mem_used = atoi ( mem_used_ch ) ;
2021-12-23 14:52:55 +01:00
ram_used = mem_used / 1024 ;
2021-12-23 13:27:30 +01:00
# else // __APPLE__
// Used ram
FILE * mem_wired_fp , * mem_active_fp , * mem_compressed_fp ;
2021-12-23 14:52:55 +01:00
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 " ) ;
2021-12-23 13:27:30 +01:00
char mem_wired_ch [ 2137 ] , mem_active_ch [ 2137 ] , mem_compressed_ch [ 2137 ] ;
2021-12-23 14:52:55 +01:00
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 )
;
2021-10-09 00:19:16 +02:00
pclose ( mem_wired_fp ) ;
pclose ( mem_active_fp ) ;
pclose ( mem_compressed_fp ) ;
2021-11-28 15:57:20 +01:00
int mem_wired = atoi ( mem_wired_ch ) ;
int mem_active = atoi ( mem_active_ch ) ;
2021-10-09 00:19:16 +02:00
int mem_compressed = atoi ( mem_compressed_ch ) ;
2021-10-14 22:48:08 +02:00
// Total ram
2021-10-09 00:19:16 +02:00
sysctlbyname ( " hw.memsize " , & mem_buffer , & mem_buffer_len , NULL , 0 ) ;
2021-12-05 13:34:56 +01:00
user_info - > ram_used = ( ( mem_wired + mem_active + mem_compressed ) * 4 / 1024 ) ;
2021-10-09 00:19:16 +02:00
2021-11-01 16:48:54 +01:00
# endif // __APPLE__
2021-11-26 18:03:14 +01:00
print_ascii ( user_info ) ;
print_info ( config_flags , user_info ) ;
2021-10-09 00:19:16 +02:00
return ;
2021-10-08 23:11:27 +02:00
}
2021-12-23 14:52:55 +01:00
// truncates the given string
void truncate_str ( char * string , int target_width ) {
2021-12-23 13:27:30 +01:00
char arr [ target_width ] ;
2021-12-23 14:52:55 +01:00
for ( int i = 0 ; i < target_width ; i + + ) arr [ i ] = string [ i ] ;
string = arr ;
2021-12-23 13:27:30 +01:00
}
// remove square brackets (for gpu names)
void remove_brackets ( char * str ) {
2021-12-23 14:52:55 +01:00
int i = 0 , j = 0 ;
while ( i < ( int ) strlen ( str ) )
if ( str [ i ] = = ' [ ' | | str [ i ] = = ' ] ' )
2021-12-23 13:27:30 +01:00
for ( j = i ; j < ( int ) strlen ( str ) ; j + + ) str [ j ] = str [ j + 1 ] ;
2021-12-23 14:52:55 +01:00
else
2021-12-23 13:27:30 +01:00
i + + ;
}
2021-12-23 14:52:55 +01:00
// uwufies kernel name
2021-12-23 13:27:30 +01:00
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 ;
2021-12-23 14:52:55 +01:00
while ( ( token = strsep ( & temp_kernel , " " ) ) ) { // split kernel name
2021-12-23 13:27:30 +01:00
strcpy ( splitted [ count ] , token ) ;
count + + ;
}
strcpy ( kernel , " " ) ;
for ( int i = 0 ; i < 16 ; i + + ) {
2021-12-23 14:52:55 +01:00
// replace kernel name with uwufied version
2021-12-23 13:27:30 +01:00
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 " ) ;
2021-12-23 14:52:55 +01:00
else KERNEL_TO_UWU ( splitted [ i ] , " opensuse-tumbleweed " , " OwOpenSUSE Tumbleweed " ) ;
2021-12-23 13:27:30 +01:00
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 " ) ;
2021-12-23 14:52:55 +01:00
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
2021-12-23 13:27:30 +01:00
// BSD
else KERNEL_TO_UWU ( splitted [ i ] , " freebsd " , " FweeBSD " ) ;
else KERNEL_TO_UWU ( splitted [ i ] , " openbsd " , " OwOpenBSD " ) ;
2021-12-23 14:52:55 +01:00
// Apple family
2021-12-23 13:27:30 +01:00
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 " )
2021-12-23 14:52:55 +01:00
HW_TO_UWU ( " cpu " , " CC \b PUwU " ) ; // for some reasons this caused a segfault, using a \b (backspace) char fixes it
2021-12-23 13:27:30 +01:00
HW_TO_UWU ( " gpu " , " GG \b PUwU " )
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 \b pple " )
HW_TO_UWU ( " electronic " , " ElectrOwOnic " )
# undef HW_TO_UWU
}
2021-12-23 14:52:55 +01:00
// get all necessary info
// I'LL COMMENT THIS FUNCTION LATER
2021-11-26 18:03:14 +01:00
# ifdef _WIN32
2021-12-05 13:34:56 +01:00
struct info get_info ( struct configuration * config_flags )
2021-12-23 14:52:55 +01:00
# else
2021-11-26 18:03:14 +01:00
struct info get_info ( )
2021-12-23 14:52:55 +01:00
# endif
{
2021-11-26 18:03:14 +01:00
struct info user_info = { 0 } ;
2021-04-15 09:28:57 +02:00
char line [ 256 ] ; // var to scan file lines
2021-04-07 14:13:15 +02:00
2021-11-01 16:48:54 +01:00
// terminal width used to truncate long names
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
ioctl ( STDOUT_FILENO , TIOCGWINSZ , & user_info . win ) ;
user_info . target_width = user_info . win . ws_col - 30 ;
# else // _WIN32
2021-11-01 16:48:54 +01:00
GetConsoleScreenBufferInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ) , & csbi ) ;
2021-11-28 15:57:20 +01:00
user_info . ws_col = csbi . srWindow . Right - csbi . srWindow . Left - 29 ;
2021-11-26 18:03:14 +01:00
user_info . ws_rows = csbi . srWindow . Bottom - csbi . srWindow . Top + 1 ;
# endif // _WIN32
2021-04-07 14:13:15 +02:00
2021-06-13 13:52:32 +02:00
// os version, cpu and board info
2021-12-05 13:34:56 +01:00
FILE * os_release = fopen ( " /etc/os-release " , " r " ) ;
2021-07-22 18:39:34 +02:00
# ifndef __FREEBSD__
2021-12-05 13:34:56 +01:00
FILE * cpuinfo = fopen ( " /proc/cpuinfo " , " r " ) ;
2021-07-22 18:39:34 +02:00
# else
2021-12-05 13:34:56 +01:00
FILE * cpuinfo = popen ( " sysctl -a | egrep -i 'hw.model' " , " r " ) ;
2021-07-22 18:39:34 +02:00
# endif
2021-12-05 13:34:56 +01:00
FILE * host_model_info =
2021-11-28 15:57:20 +01:00
fopen ( " /sys/devices/virtual/dmi/id/board_name " ,
2021-12-18 23:24:58 +01:00
" r " ) ; // try to get board name
2021-11-26 18:03:14 +01:00
if ( ! host_model_info )
2021-11-28 15:57:20 +01:00
host_model_info = fopen ( " /sys/devices/virtual/dmi/id/product_name " ,
" r " ) ; // if couldn't then try another
if ( ! host_model_info ) // if failed
host_model_info = fopen ( " /etc/hostname " , " r " ) ; // etc.
if ( host_model_info ) { // if succeeded to open one of the file
2021-11-26 18:03:14 +01:00
fgets ( line , 256 , host_model_info ) ;
line [ strlen ( line ) - 1 ] = ' \0 ' ;
sprintf ( user_info . host_model , " %s " , line ) ;
fclose ( host_model_info ) ;
}
# ifdef _WIN32
2021-11-01 16:48:54 +01:00
host_model_info = popen ( " wmic computersystem get model " , " r " ) ;
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , host_model_info ) ) {
2021-11-01 16:48:54 +01:00
if ( strstr ( line , " Model " ) ! = 0 )
continue ;
2021-11-28 15:57:20 +01:00
else {
2021-11-26 18:03:14 +01:00
sprintf ( user_info . host_model , " %s " , line ) ;
user_info . host_model [ strlen ( user_info . host_model ) - 2 ] = ' \0 ' ;
2021-11-01 16:48:54 +01:00
break ;
}
}
2021-11-04 15:33:04 +01:00
# elif defined(__FREEBSD__) || defined(__APPLE__)
2021-11-28 15:57:20 +01:00
# if defined(__FREEBSD__)
# define HOSTCTL "hw.hv_vendor"
# elif defined(__APPLE__)
# define HOSTCTL "hw.model"
# endif
host_model_info = popen ( " sysctl -a " HOSTCTL , " r " ) ;
2021-07-24 15:37:16 +02:00
while ( fgets ( line , sizeof ( line ) , host_model_info ) )
2021-12-06 11:52:08 +01:00
if ( sscanf ( line , HOSTCTL " : %[^ \n ] " , user_info . host_model ) ) break ;
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-12-05 13:34:56 +01:00
FILE * host_model_version =
2021-11-28 15:57:20 +01:00
fopen ( " /sys/devices/virtual/dmi/id/product_version " , " r " ) ;
2021-05-03 03:46:55 +02:00
2021-11-28 15:57:20 +01:00
if ( os_release ) { // get normal vars
2021-11-01 16:48:54 +01:00
while ( fgets ( line , sizeof ( line ) , os_release ) )
2021-12-23 13:27:30 +01:00
if ( sscanf ( line , " \n ID= \" %s \" " , user_info . os_name ) | |
sscanf ( line , " \n ID=%s " , user_info . os_name ) )
2021-11-01 16:48:54 +01:00
break ;
2021-09-10 01:37:20 +02:00
2021-11-28 15:57:20 +01:00
// trying to detect amogos because in its os-release file ID value is
// just "debian"
2021-12-23 13:27:30 +01:00
if ( strcmp ( user_info . os_name , " debian " ) = = 0 | |
strcmp ( user_info . os_name , " raspbian " ) = =
2021-11-28 15:57:20 +01:00
0 ) // will be removed when amogos will have an os-release file
// with ID=amogos
2021-11-01 16:48:54 +01:00
{
2021-12-05 13:34:56 +01:00
DIR * amogos_plymouth = opendir ( " /usr/share/plymouth/themes/amogos " ) ;
2021-11-28 15:57:20 +01:00
if ( amogos_plymouth ) {
2021-11-01 16:48:54 +01:00
closedir ( amogos_plymouth ) ;
2021-12-23 13:27:30 +01:00
sprintf ( user_info . os_name , " amogos " ) ;
2021-09-10 01:37:20 +02:00
}
2021-11-01 16:48:54 +01:00
}
2021-12-18 21:38:58 +01:00
if ( host_model_version ) {
while ( fgets ( line , sizeof ( line ) , host_model_version ) )
if ( sscanf ( line , " %[^ \n ] " , user_info . host_model_version ) ) break ;
2021-11-28 15:57:20 +01:00
if ( host_model_version ) {
2021-11-01 16:48:54 +01:00
char version [ 32 ] ;
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , host_model_version ) ) {
if ( sscanf ( line , " %[^ \n ] " , version ) ) {
2021-12-18 21:38:58 +01:00
strcat ( user_info . host_model_version , " " ) ;
strcat ( user_info . host_model_version , version ) ;
2021-11-01 16:48:54 +01:00
break ;
2021-09-10 00:51:37 +02:00
}
}
2021-06-13 13:57:28 +02:00
}
2021-05-03 03:46:55 +02:00
}
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , cpuinfo ) ) {
2021-07-22 18:39:34 +02:00
# ifdef __FREEBSD__
2021-11-26 18:03:14 +01:00
if ( sscanf ( line , " hw.model: %[^ \n ] " , user_info . cpu_model ) )
2021-07-22 18:39:34 +02:00
# else
2021-11-26 18:03:14 +01:00
if ( sscanf ( line , " model name : %[^ \n ] " , user_info . cpu_model ) )
2021-04-15 09:28:57 +02:00
break ;
2021-11-01 16:48:54 +01:00
# endif // __FREEBSD__
}
2021-12-05 13:34:56 +01:00
char * tmp_user = getenv ( " USER " ) ;
2021-10-03 23:48:10 +02:00
if ( tmp_user = = NULL )
2021-11-26 18:03:14 +01:00
sprintf ( user_info . user , " %s " , " " ) ;
2021-10-03 23:48:10 +02:00
else
2021-11-26 18:03:14 +01:00
sprintf ( user_info . user , " %s " , tmp_user ) ;
2021-11-01 16:48:54 +01:00
fclose ( os_release ) ;
2021-11-28 15:57:20 +01:00
} else { // try for android vars, next for Apple var, or unknown system
2021-12-05 13:34:56 +01:00
DIR * system_app = opendir ( " /system/app/ " ) ;
DIR * system_priv_app = opendir ( " /system/priv-app/ " ) ;
DIR * library = opendir ( " /Library/ " ) ;
2021-11-28 15:57:20 +01:00
if ( system_app & & system_priv_app ) { // android
2021-04-07 14:13:15 +02:00
closedir ( system_app ) ;
closedir ( system_priv_app ) ;
2021-12-23 13:27:30 +01:00
sprintf ( user_info . os_name , " android " ) ;
2021-04-07 14:13:15 +02:00
// android vars
2021-12-05 13:34:56 +01:00
FILE * whoami = popen ( " whoami " , " r " ) ;
2021-11-26 18:03:14 +01:00
if ( fscanf ( whoami , " %s " , user_info . user ) = = 3 )
sprintf ( user_info . user , " unknown " ) ;
2021-04-07 14:13:15 +02:00
fclose ( whoami ) ;
2021-11-01 16:55:33 +01:00
host_model_info = popen ( " getprop ro.product.model " , " r " ) ;
2021-06-13 13:52:32 +02:00
while ( fgets ( line , sizeof ( line ) , host_model_info ) )
2021-11-28 15:57:20 +01:00
if ( sscanf ( line , " %[^ \n ] " , user_info . host_model ) ) break ;
2021-07-22 18:39:34 +02:00
# ifndef __FREEBSD__
2021-04-07 14:13:15 +02:00
while ( fgets ( line , sizeof ( line ) , cpuinfo ) )
2021-11-28 15:57:20 +01:00
if ( sscanf ( line , " Hardware : %[^ \n ] " ,
user_info . cpu_model ) )
2021-04-15 09:28:57 +02:00
break ;
2021-07-22 18:39:34 +02:00
# endif
2021-11-28 15:57:20 +01:00
} else if ( library ) // Apple
2021-04-16 10:48:39 +02:00
{
closedir ( library ) ;
# ifdef __APPLE__
2021-11-28 15:57:20 +01:00
sysctlbyname ( " machdep.cpu.brand_string " , & cpu_buffer ,
& cpu_buffer_len , NULL , 0 ) ;
2021-04-15 22:59:43 +02:00
2021-12-06 15:25:25 +01:00
# ifndef __IPHONE__
2021-12-23 13:27:30 +01:00
sprintf ( user_info . os_name , " macos " ) ;
2021-11-28 15:57:20 +01:00
# else
2021-12-23 13:27:30 +01:00
sprintf ( user_info . os_name , " ios " ) ;
2021-11-28 15:57:20 +01:00
# endif
2021-11-26 18:03:14 +01:00
sprintf ( user_info . cpu_model , " %s " , cpu_buffer ) ;
2021-04-16 10:48:39 +02:00
# endif
2021-11-28 15:57:20 +01:00
} else
2021-12-23 13:27:30 +01:00
sprintf ( user_info . os_name , " unknown " ) ;
2021-04-07 14:13:15 +02:00
}
2021-07-22 18:39:34 +02:00
# ifndef __FREEBSD__
2021-04-07 14:13:15 +02:00
fclose ( cpuinfo ) ;
2021-07-22 18:39:34 +02:00
# endif
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
gethostname ( user_info . host , 256 ) ;
// #endif // _WIN32
2021-12-05 13:34:56 +01:00
char * tmp_shell = getenv ( " SHELL " ) ;
2021-10-02 22:34:37 +02:00
if ( tmp_shell = = NULL )
2021-11-26 18:03:14 +01:00
sprintf ( user_info . shell , " %s " , " " ) ;
2021-10-02 22:34:37 +02:00
else
2021-11-26 18:03:14 +01:00
sprintf ( user_info . shell , " %s " , tmp_shell ) ;
if ( strlen ( user_info . shell ) > 16 )
2021-11-28 15:57:20 +01:00
memmove ( & user_info . shell , & user_info . shell [ 27 ] ,
strlen ( user_info . shell ) ) ; // android shell was too long, this
// works only for termux
2021-11-01 16:48:54 +01:00
# else
cpuinfo = popen ( " wmic cpu get caption " , " r " ) ;
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , cpuinfo ) ) {
2021-11-01 16:48:54 +01:00
if ( strstr ( line , " Caption " ) ! = 0 )
continue ;
2021-11-28 15:57:20 +01:00
else {
2021-11-26 18:03:14 +01:00
sprintf ( user_info . cpu_model , " %s " , line ) ;
user_info . cpu_model [ strlen ( user_info . cpu_model ) - 2 ] = ' \0 ' ;
2021-11-01 16:48:54 +01:00
break ;
}
}
2021-12-05 13:34:56 +01:00
FILE * user_host_fp = popen ( " wmic computersystem get username " , " r " ) ;
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , user_host_fp ) ) {
2021-11-01 16:48:54 +01:00
if ( strstr ( line , " UserName " ) ! = 0 )
continue ;
2021-11-28 15:57:20 +01:00
else {
2021-11-26 18:03:14 +01:00
sscanf ( line , " %[^ \\ ]%s " , user_info . host , user_info . user ) ;
2021-11-28 15:57:20 +01:00
memmove ( user_info . user , user_info . user + 1 ,
sizeof ( user_info . user ) - 1 ) ;
2021-11-01 16:48:54 +01:00
break ;
}
}
2021-12-05 13:34:56 +01:00
FILE * shell_fp = popen ( " powershell $PSVersionTable " , " r " ) ;
2021-11-26 18:03:14 +01:00
sprintf ( user_info . shell , " PowerShell " ) ;
2021-11-01 16:48:54 +01:00
char tmp_shell [ 64 ] ;
while ( fgets ( line , sizeof ( line ) , shell_fp ) )
if ( sscanf ( line , " PSVersion %s " , tmp_shell ) ! = 0 )
break ;
2021-11-26 18:03:14 +01:00
strcat ( user_info . shell , tmp_shell ) ;
# endif // _WIN32
2021-04-07 14:13:15 +02:00
// truncate CPU name
2021-12-23 14:52:55 +01:00
truncate_str ( user_info . cpu_model , user_info . target_width ) ;
2021-04-07 14:13:15 +02:00
2021-11-01 16:48:54 +01:00
// system resources
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
uname ( & user_info . sys_var ) ;
# endif // _WIN32
2021-04-16 14:10:33 +02:00
# ifndef __APPLE__
2021-11-28 15:57:20 +01:00
# ifndef __FREEBSD__
# ifndef _WIN32
sysinfo ( & user_info . sys ) ; // somehow this function has to be called again in
// print_info()
# else // _WIN32
2021-11-26 18:03:14 +01:00
GetSystemInfo ( & user_info . sys ) ;
2021-11-28 15:57:20 +01:00
# endif // _WIN32
# endif
2021-04-16 14:10:33 +02:00
# endif
2021-04-07 14:13:15 +02:00
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
2021-12-23 14:52:55 +01:00
truncate_str ( user_info . sys_var . release , user_info . target_width ) ;
2021-11-28 15:57:20 +01:00
sprintf ( user_info . kernel , " %s %s %s " , user_info . sys_var . sysname ,
user_info . sys_var . release , user_info . sys_var . machine ) ;
2021-12-23 14:52:55 +01:00
truncate_str ( user_info . kernel , user_info . target_width ) ;
2021-11-26 18:03:14 +01:00
# else // _WIN32
2021-12-23 13:27:30 +01:00
sprintf ( user_info . os_name , " windows " ) ;
2021-12-05 13:34:56 +01:00
FILE * kernel_fp = popen ( " wmic computersystem get systemtype " , " r " ) ;
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , kernel_fp ) ) {
2021-11-01 16:48:54 +01:00
if ( strstr ( line , " SystemType " ) ! = 0 )
continue ;
2021-11-28 15:57:20 +01:00
else {
2021-11-26 18:03:14 +01:00
sprintf ( user_info . kernel , " %s " , line ) ;
user_info . kernel [ strlen ( user_info . kernel ) - 2 ] = ' \0 ' ;
2021-11-01 16:48:54 +01:00
break ;
}
}
2021-11-28 15:57:20 +01:00
if ( kernel_fp ! = NULL ) pclose ( kernel_fp ) ;
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-04-07 14:13:15 +02:00
2021-11-01 16:48:54 +01:00
// ram
2021-04-15 22:59:43 +02:00
# ifndef __APPLE__
2021-11-28 15:57:20 +01:00
# ifdef _WIN32
2021-12-05 13:34:56 +01:00
FILE * mem_used_fp = popen ( " wmic os get freevirtualmemory " , " r " ) ;
FILE * mem_total_fp = popen ( " wmic os get totalvirtualmemorysize " , " r " ) ;
2021-11-01 16:48:54 +01:00
char mem_used_ch [ 2137 ] = { 0 } , mem_total_ch [ 2137 ] = { 0 } ;
2021-11-28 15:57:20 +01:00
while ( fgets ( mem_total_ch , sizeof ( mem_total_ch ) , mem_total_fp ) ! = NULL ) {
2021-11-01 16:48:54 +01:00
if ( strstr ( mem_total_ch , " TotalVirtualMemorySize " ) ! = 0 )
continue ;
else if ( strstr ( mem_total_ch , " " ) = = 0 )
continue ;
else
2021-11-26 18:03:14 +01:00
user_info . ram_total = atoi ( mem_total_ch ) / 1024 ;
2021-11-01 16:48:54 +01:00
}
2021-11-28 15:57:20 +01:00
while ( fgets ( mem_used_ch , sizeof ( mem_used_ch ) , mem_used_fp ) ! = NULL ) {
2021-11-01 16:48:54 +01:00
if ( strstr ( mem_used_ch , " FreeVirtualMemory " ) ! = 0 )
continue ;
else if ( strstr ( mem_used_ch , " " ) = = 0 )
continue ;
else
2021-11-28 15:57:20 +01:00
user_info . ram_used =
user_info . ram_total - ( atoi ( mem_used_ch ) / 1024 ) ;
2021-11-01 16:48:54 +01:00
}
pclose ( mem_used_fp ) ;
pclose ( mem_total_fp ) ;
2021-11-28 15:57:20 +01:00
# else
2021-12-05 13:34:56 +01:00
FILE * meminfo ;
2021-04-07 14:13:15 +02:00
2021-11-28 15:57:20 +01:00
# ifdef __FREEBSD__
2021-11-01 16:55:33 +01:00
meminfo = popen ( " LANG=EN_us freecolor -om 2> /dev/null " , " r " ) ;
2021-11-28 15:57:20 +01:00
# else
2021-11-01 16:55:33 +01:00
meminfo = popen ( " LANG=EN_us free -m 2> /dev/null " , " r " ) ;
2021-11-28 15:57:20 +01:00
# endif
2021-05-31 01:04:32 +02:00
while ( fgets ( line , sizeof ( line ) , meminfo ) )
2021-11-28 15:57:20 +01:00
// free command prints like this: "Mem:" total used free shared
// buff/cache available
2021-11-26 18:03:14 +01:00
sscanf ( line , " Mem: %d %d " , & user_info . ram_total , & user_info . ram_used ) ;
2021-05-31 01:04:32 +02:00
fclose ( meminfo ) ;
2021-11-28 15:57:20 +01:00
# endif
2021-04-15 22:59:43 +02:00
# else
// Used
2021-04-16 10:48:39 +02:00
FILE * mem_wired_fp , * mem_active_fp , * mem_compressed_fp ;
2021-11-28 15:57:20 +01:00
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 " ) ;
2021-04-15 22:59:43 +02:00
char mem_wired_ch [ 2137 ] , mem_active_ch [ 2137 ] , mem_compressed_ch [ 2137 ] ;
2021-11-28 15:57:20 +01:00
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 ) {
2021-04-16 10:48:39 +02:00
}
2021-04-15 22:59:43 +02:00
}
}
2021-04-16 10:48:39 +02:00
pclose ( mem_wired_fp ) ;
pclose ( mem_active_fp ) ;
pclose ( mem_compressed_fp ) ;
2021-04-15 22:59:43 +02:00
2021-11-28 15:57:20 +01:00
int mem_wired = atoi ( mem_wired_ch ) ;
int mem_active = atoi ( mem_active_ch ) ;
2021-04-15 22:59:43 +02:00
int mem_compressed = atoi ( mem_compressed_ch ) ;
// Total
sysctlbyname ( " hw.memsize " , & mem_buffer , & mem_buffer_len , NULL , 0 ) ;
2021-12-06 11:52:08 +01:00
user_info . ram_used = ( ( mem_wired + mem_active + mem_compressed ) * 4 / 1024 ) ;
user_info . ram_total = mem_buffer / 1024 / 1024 ;
2021-04-15 22:59:43 +02:00
# endif
2021-04-07 14:13:15 +02:00
/* ---------- gpu ---------- */
2021-11-28 15:57:20 +01:00
int gpun = 0 ; // number of the gpu that the program is searching for to put
// in the array
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
2021-04-07 14:13:15 +02:00
setenv ( " LANG " , " en_US " , 1 ) ; // force language to english
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-12-05 13:34:56 +01:00
FILE * gpu ;
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
2021-11-01 16:55:33 +01:00
gpu = popen ( " lshw -class display 2> /dev/null " , " r " ) ;
2021-04-07 14:13:15 +02:00
2021-07-23 11:06:46 +02:00
// add all gpus to the array gpu_model
2021-04-07 14:13:15 +02:00
while ( fgets ( line , sizeof ( line ) , gpu ) )
2021-11-26 18:03:14 +01:00
if ( sscanf ( line , " product: %[^ \n ] " , user_info . gpu_model [ gpun ] ) )
2021-04-15 09:28:57 +02:00
gpun + + ;
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-04-07 14:13:15 +02:00
2021-11-28 15:57:20 +01:00
if ( strlen ( user_info . gpu_model [ 0 ] ) < 2 ) {
2021-04-07 14:13:15 +02:00
// get gpus with lspci command
2021-12-23 13:27:30 +01:00
if ( strcmp ( user_info . os_name , " android " ) ! = 0 ) {
2021-04-16 10:48:39 +02:00
# ifndef __APPLE__
2021-11-28 15:57:20 +01:00
# ifdef _WIN32
2021-11-01 17:12:19 +01:00
gpu = popen ( " wmic PATH Win32_VideoController GET Name " , " r " ) ;
2021-11-28 15:57:20 +01:00
# else
gpu = popen ( " lspci -mm 2> /dev/null | grep \" VGA \" | awk -F ' \" ' "
" '{print $4 $5 $6}' " ,
" r " ) ;
# endif
2021-05-31 01:04:32 +02:00
# else
2021-11-28 15:57:20 +01:00
gpu = popen ( " system_profiler SPDisplaysDataType | awk -F ': ' "
" '/Chipset Model: /{ print $2 }' " ,
" r " ) ;
2021-05-31 01:04:32 +02:00
# endif
2021-11-28 15:57:20 +01:00
} else
2021-11-01 16:55:33 +01:00
gpu = popen ( " getprop ro.hardware.vulkan 2> /dev/null " , " r " ) ;
2021-04-07 14:13:15 +02:00
}
// get all the gpus
2021-11-28 15:57:20 +01:00
while ( fgets ( line , sizeof ( line ) , gpu ) ) {
2021-11-01 17:12:19 +01:00
if ( strstr ( line , " Name " ) )
continue ;
else if ( strlen ( line ) = = 2 )
continue ;
// ^^^ for windows
2021-11-26 18:03:14 +01:00
else if ( sscanf ( line , " %[^ \n ] " , user_info . gpu_model [ gpun ] ) )
2021-04-15 09:28:57 +02:00
gpun + + ;
2021-04-07 14:13:15 +02:00
}
fclose ( gpu ) ;
// truncate GPU name and remove square brackets
2021-11-28 15:57:20 +01:00
for ( int i = 0 ; i < gpun ; i + + ) {
2021-11-26 18:03:14 +01:00
remove_brackets ( user_info . gpu_model [ i ] ) ;
2021-12-23 14:52:55 +01:00
truncate_str ( user_info . gpu_model [ i ] , user_info . target_width ) ;
2021-04-07 14:13:15 +02:00
}
2021-11-01 17:12:19 +01:00
// Resolution
2021-11-26 18:03:14 +01:00
# ifndef _WIN32
2021-12-05 13:34:56 +01:00
FILE * resolution =
2021-11-28 15:57:20 +01:00
popen ( " xwininfo -root 2> /dev/null | grep -E 'Width|Height' " , " r " ) ;
while ( fgets ( line , sizeof ( line ) , resolution ) ) {
2021-11-26 18:03:14 +01:00
sscanf ( line , " Width: %d " , & user_info . screen_width ) ;
sscanf ( line , " Height: %d " , & user_info . screen_height ) ;
2021-04-15 23:52:12 +02:00
}
2021-11-26 18:03:14 +01:00
# endif // _WIN32
2021-04-15 23:52:12 +02:00
2021-12-23 13:27:30 +01:00
if ( strcmp ( user_info . os_name , " windows " ) )
MOVE_CURSOR = " \033 [21C " ;
2021-11-01 19:44:02 +01:00
2021-11-26 18:03:14 +01:00
// package count
# ifdef _WIN32
user_info . pkgs = pkgman ( & user_info , config_flags ) ;
# else // _WIN32
user_info . pkgs = pkgman ( & user_info ) ;
# endif // _WIN32
2021-10-08 23:11:27 +02:00
2021-11-26 18:03:14 +01:00
uwu_kernel ( user_info . kernel ) ;
2021-10-08 23:11:27 +02:00
2021-11-26 18:03:14 +01:00
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 . host_model ) ;
return user_info ;
2021-12-23 14:52:55 +01:00
} // get_info
2021-03-06 21:17:29 +01:00
2021-12-23 14:52:55 +01:00
/* prints distribution list
distributions are listed by distribution branch
to make the output easier to understand by the user . */
void list ( char * arg ) {
2021-04-15 09:28:57 +02:00
printf ( " %s -d <options> \n "
" Available distributions: \n "
" %sArch linux %sbased: \n "
2021-11-28 15:57:20 +01:00
" %sarch, arcolinux, %sartix, endeavouros %smanjaro, "
" manjaro-arm, %sxerolinux \n \n "
2021-04-15 09:28:57 +02:00
" %sDebian/%sUbuntu %sbased: \n "
2021-11-28 15:57:20 +01:00
" %samogos, debian, %slinuxmint, neon %spop, %sraspbian "
" %subuntu \n \n "
2021-05-03 01:04:18 +02:00
" %sBSD %sbased: \n "
2021-11-06 00:34:53 +01:00
" %sfreebsd, %sopenbsd, %sm%sa%sc%so%ss, %sios \n \n "
2021-04-15 09:28:57 +02:00
" %sOther/spare distributions: \n "
2021-11-28 15:57:20 +01:00
" %salpine, %sfedora, %sgentoo, %sslackware, %ssolus, %svoid, "
" opensuse-leap, android, %sgnu, guix, %swindows, %sunknown \n \n " ,
2021-12-23 14:52:55 +01:00
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
2021-11-28 15:57:20 +01:00
NORMAL , BLUE , BLUE , PINK , MAGENTA , WHITE , GREEN , YELLOW , BLUE ,
WHITE ) ; // Other/spare distributions colors
2021-03-08 15:49:50 +01:00
}
2021-12-23 14:52:55 +01:00
// prints the usage
2021-12-05 13:34:56 +01:00
void usage ( char * arg ) {
2021-04-15 09:28:57 +02:00
printf ( " Usage: %s <args> \n "
2021-10-08 23:11:27 +02:00
" -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 "
2021-12-06 15:25:25 +01:00
# ifndef __IPHONE__
2021-12-23 14:52:55 +01:00
" -i, --image prints logo as image and use a custom image if provided \n "
2021-10-08 23:11:27 +02:00
" %sworks in most terminals \n "
2021-11-06 00:34:53 +01:00
# else
2021-12-23 14:52:55 +01:00
" -i, --image prints logo as image and use a custom image if provided \n "
2021-11-06 00:34:53 +01:00
" %sdisabled under iOS \n "
# endif
2021-10-08 23:11:27 +02:00
" read README.md for more info%s \n "
" -l, --list lists all supported distributions \n "
2021-12-23 14:52:55 +01:00
" -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 " ,
2021-11-06 00:34:53 +01:00
arg ,
2021-12-06 15:25:25 +01:00
# ifndef __IPHONE__
2021-11-06 00:34:53 +01:00
BLUE ,
# else
RED ,
# endif
NORMAL ) ;
2021-03-09 11:35:18 +01:00
}
2021-11-26 18:03:14 +01:00
# ifdef _WIN32
2021-11-28 15:57:20 +01:00
// 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
2021-12-05 13:34:56 +01:00
char * strsep ( char * * stringp , const char * delim ) {
char * start = * stringp ;
char * p ;
2021-11-01 16:48:54 +01:00
p = ( start ! = NULL ) ? strpbrk ( start , delim ) : NULL ;
if ( p = = NULL )
* stringp = NULL ;
2021-11-28 15:57:20 +01:00
else {
* p = ' \0 ' ;
2021-11-01 16:48:54 +01:00
* stringp = p + 1 ;
}
return start ;
}
# endif
2021-12-23 13:27:30 +01:00
// the main function is on the bottom of the file to avoid double function declarations
int main ( int argc , char * argv [ ] ) {
2021-12-23 14:52:55 +01:00
char * cache_env = getenv ( " UWUFETCH_CACHE_ENABLED " ) ; // getting cache env variable
2021-12-23 13:27:30 +01:00
struct configuration config_flags ;
struct info user_info = { 0 } ;
2021-12-23 14:52:55 +01:00
if ( cache_env ! = NULL ) { // if cache env variable is set, read itz value
2021-12-23 13:27:30 +01:00
int cache_enabled = 0 ;
char buffer [ 128 ] ;
2021-07-04 19:54:28 +02:00
2021-12-23 13:27:30 +01:00
sscanf ( cache_env , " %4[TRUEtrue1] " , buffer ) ;
2021-12-23 14:52:55 +01:00
cache_enabled = ( strcmp ( buffer , " true " ) = = 0 | | strcmp ( buffer , " TRUE " ) = = 0 | | strcmp ( buffer , " 1 " ) = = 0 ) ; // enable the cache if necessary
2021-12-23 13:27:30 +01:00
if ( cache_enabled ) {
// if no cache file found write to it
if ( ! read_cache ( & user_info ) ) {
user_info = get_info ( & config_flags ) ;
write_cache ( & user_info ) ;
}
2021-12-23 14:52:55 +01:00
config_flags = parse_config ( & user_info ) ; // reading the config
2021-12-23 13:27:30 +01:00
print_cache ( & config_flags , & user_info ) ;
return 0 ;
}
2021-07-04 19:38:10 +02:00
}
2021-12-23 13:27:30 +01:00
# ifdef _WIN32
2021-12-23 14:52:55 +01:00
// packages disabled by default because chocolatey is too slow
2021-12-23 13:27:30 +01:00
config_flags . show_pkgs = 0 ;
# endif
2021-05-03 03:46:55 +02:00
2021-12-23 14:52:55 +01:00
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 ' } ,
{ " write-cache " , no_argument , NULL , ' w ' } ,
{ " help " , no_argument , NULL , ' h ' } ,
{ " image " , optional_argument , NULL , ' i ' } ,
{ " list " , no_argument , NULL , ' l ' } ,
{ NULL , 0 , NULL , 0 } } ;
user_info = get_info ( & config_flags ) ; // get the info to modify it with cmdline options
config_flags = parse_config ( & user_info ) ; // same as user_info
// reading cmdline options
while ( ( opt = getopt_long ( argc , argv , " ac:d:hi::lw " , long_options , NULL ) ) ! = - 1 ) {
2021-12-23 13:27:30 +01:00
switch ( opt ) {
2021-12-23 14:52:55 +01:00
case ' a ' : // set ascii logo as output
2021-12-23 13:27:30 +01:00
config_flags . ascii_image_flag = 0 ;
break ;
2021-12-23 14:52:55 +01:00
case ' c ' : // set the config directory
2021-12-23 13:27:30 +01:00
user_info . config_directory = optarg ;
break ;
2021-12-23 14:52:55 +01:00
case ' d ' : // set the distribution name
2021-12-23 13:27:30 +01:00
if ( optarg ) sprintf ( user_info . os_name , " %s " , optarg ) ;
break ;
case ' h ' :
usage ( argv [ 0 ] ) ;
return 0 ;
2021-12-23 14:52:55 +01:00
case ' i ' : // set ascii logo as output
2021-12-23 13:27:30 +01:00
config_flags . ascii_image_flag = 1 ;
2021-12-23 14:52:55 +01:00
if ( ! optarg & & argv [ optind ] ! = NULL & & argv [ optind ] [ 0 ] ! = ' - ' ) // set default image name
2021-12-23 13:27:30 +01:00
sprintf ( user_info . image_name , " %s " , argv [ optind + + ] ) ;
2021-12-23 14:52:55 +01:00
else if ( optarg ) // set user-defined image name
2021-12-23 13:27:30 +01:00
sprintf ( user_info . image_name , " %s " , optarg ) ;
break ;
case ' l ' :
list ( argv [ 0 ] ) ;
return 0 ;
case ' w ' :
write_cache ( & user_info ) ;
print_cache ( & config_flags , & user_info ) ;
return 0 ;
default :
break ;
2021-04-07 14:13:15 +02:00
}
}
2021-12-23 14:52:55 +01:00
if ( ( argc = = 1 & & config_flags . ascii_image_flag = = 0 ) | | ( argc > 1 & & config_flags . ascii_image_flag = = 0 ) )
2021-12-23 13:27:30 +01:00
print_ascii ( & user_info ) ;
2021-12-23 14:52:55 +01:00
else if ( config_flags . ascii_image_flag = = 1 )
2021-12-23 13:27:30 +01:00
print_image ( & user_info ) ;
print_info ( & config_flags , & user_info ) ;
2021-12-23 14:52:55 +01:00
return 0 ;
2021-07-22 15:31:34 +02:00
}