Initial commit

This commit is contained in:
Јован Ђокић-Шумарац 2021-08-28 10:01:36 +02:00
parent 45cd9425fc
commit b0da4b5d22
8 changed files with 303 additions and 642 deletions

19
LICENSE
View file

@ -1,19 +0,0 @@
Copyright 2020 vojjvoda
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,20 +1,20 @@
PREFIX = /usr/local
CC = gcc
CFLAGS = -lpci
CFLAGS = -lX11
all: fetchy
all: minchy
fetchy: fetchy.c
$(CC) fetchy.c -o $@ $(CFLAGS)
minchy: minchy.c
$(CC) minchy.c -o $@ $(CFLAGS)
clean:
-rm -f fetchy
-rm -f minchy
install: all
install -Dm755 fetchy $(DESTDIR)$(PREFIX)/bin/fetchy
install -Dm755 minchy $(DESTDIR)$(PREFIX)/bin/minchy
uninstall:
-rm -f $(DESTDIR)$(PREFIX)/bin/fetchy
-rm -f $(DESTDIR)$(PREFIX)/bin/minchy
.PHONY: all install uninstall clean

View file

@ -1,35 +0,0 @@
# Maintainer: Јован Ђокић-Шумарац <sumarac@protonmail.com>
pkgname=fetchy-git
pkgver=2.2
pkgrel=1
epoch=
pkgdesc="Cli system info tool written in C. "
arch=(x86_64)
url="https://gitlab.com/vojjvoda/fetchy.git"
license=('MIT')
groups=()
depends=()
makedepends=(make)
checkdepends=()
optdepends=()
provides=(fetchy)
conflicts=(fetchy)
replaces=()
backup=()
options=()
install=
changelog=
source=("git+$url")
noextract=()
md5sums=('SKIP')
validpgpkeys=()
build() {
cd fetchy
make
}
package() {
cd fetchy
make DESTDIR="$pkgdir" PREFIX="/usr" install
}

View file

@ -1,39 +0,0 @@
#+TITLE: Fetchy
Currently supported : Arch, Artix, Arco, Manjaro, Debian and Ubuntu. (more to come)
**** TESTERS NEEDED
* What is fetchy?
#+CAPTION: fetchy Screenshot
#+ATTR_HTML: :alt fetchy Screenshot :title fetchy Screenshot :align left
[[https://gitlab.com/vojjvoda/fetchy/-/raw/master/arch.png]]
**** fetchy - simple cli system information tool written in C.
The whole purpose of fetchy is to give you information on some system aspects, while remaining concise. It is minimal and soon will have a config.h file, similar to suckless programs, where you will be able to disable or enable info. The biggest motivation for this project, besides of being concise, is speed. Neofetch is a 10K line bash script which executes rather slowly. Fetchy runs fo about 20ms on first run and about 2ms on subsequent runs, due to caching of cpu and gpu info, as it is the slowest part of the program. Cache file is located in ~/.local/share/fetchy.cache
* Installation
** AUR
#+begin_src
yay -S fetchy-git
#+end_src
** Source
#+begin_src
git clone https://gitlab.com/vojjvoda/fetchy
cd fetchy
sudo make install
#+end_src
* Running
#+begin_src
fetchy -{x,a,r,m,u,d}
#+end_src
Arguments are purely for testing purposes for now, all they do is change ascii art. Enjoy !

BIN
arch.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

464
fetchy.c
View file

@ -1,464 +0,0 @@
#pragma GCC diagnostic ignored "-Wunused-function"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
#include <pci/pci.h>
#define BUF_SIZE 50
#define COLS 8
#define ROWS 100
//for easier checks
#define SUPPORTED_OS "xadurm"
#define ARCH_BASED "axmr"
#define DEBIAN_BASED "du"
#define OS_TABLE "a:Arch|x:Artix|r:Arco|m:Manjaro|u:Ubuntu|d:Debian"
//ascii art header file
#include "logos.h"
// standardish functions
void read_line(char x);
void cache_info(char **cpu_name, char **gpu);
static int count_files(DIR *package_dir);
// 'get info' functions
static char *get_sys(char *s_os, char *os_name);
static char *get_kernel(char *kern_name);
static char *get_uptime(char *uptime);
static char *get_RAM(char *ram_info);
static char *get_cpu(char *cpuname);
static char *get_gpu(char *gpu);
static char *get_packages(char *package_count);
// final function
void concatenate_print(char *os, char *cpu_name, char *gpu);
// easier if global, don't hate me
char sys;
int logo_number = 0;
int main(int argc, char *argv[]){
char *os_name = NULL,
*cpu_name = NULL,
*gpu = NULL,
*s_os = SUPPORTED_OS,
*os = malloc(BUF_SIZE);
// if cache file exits, read it, otherwise cache info
cache_info(&cpu_name, &gpu);
os = get_sys(s_os, os_name);
// check if custom ascii art argument is passed
if ( argv[1] != NULL ) {
if ( strchr(SUPPORTED_OS, *(argv[1] + 1)) )
logo_number = (int) (strchr(s_os, *(argv[1] + 1) ) - s_os);
else {
fprintf(stderr, "\n\nArgument not supported\n\n");
exit(EXIT_FAILURE);
}
}
concatenate_print( os, cpu_name, gpu);
free(os_name);
free(cpu_name);
free(gpu);
free(os);
return EXIT_SUCCESS;
}
void read_line(char x) {
int c;
while (( c = getchar()) != x && c != EOF) {}
}
void truncate_spaces(char *str) {
int src = 0, dst = 0, index, i = -1;
while(*(str + dst) == ' ') dst++;
while(*(str + dst) != '\0') {
*(str + src) = *(str + dst);
if(*(str + (dst++)) == ' ')
while(*(str + dst) == ' ') dst++;
src++;
}
*(str + src) = '\0';
i = 0;
while(str[i] != '\0'){
if(str[i] != ' ' && str[i] != '\t' && str[i] != '\n'){
index= i;
}
i++;
}
str[index + 1] = '\0';
}
void cache_info(char **cpu_name, char **gpu) {
char *cache_path = malloc(BUF_SIZE * 2);
FILE *f_cache = NULL;
// construct path to file
snprintf(cache_path, BUF_SIZE * 2, "%s/.local/share/fetchy.cache", getenv("HOME"));
if( (f_cache = fopen(cache_path, "r")) ){
char *line = malloc(BUF_SIZE * 4);
*cpu_name = malloc(BUF_SIZE * 4);
*gpu = malloc(BUF_SIZE * 4);
//get CPU
fgets(line, BUF_SIZE * 4, f_cache);
truncate_spaces(line);
snprintf(*cpu_name, BUF_SIZE * 4, "\x1b[36mCPU\x1b[0m -> %s", strchr(line, ':') +2);
//get GPU
fgets(line, BUF_SIZE * 4, f_cache);
truncate_spaces(line);
snprintf(*gpu, BUF_SIZE * 4, "\x1b[36mGPU\x1b[0m -> %s", strchr(line, ':') +2);
fclose(f_cache);
free(line);
}
else {
f_cache = fopen(cache_path, "w");
if( f_cache == NULL ){
printf("\nCan't open cache file.\n");
exit(EXIT_FAILURE);
}
// Write info to file
fprintf(f_cache, "CPU : %s\n", get_cpu(*cpu_name));
fprintf(f_cache, "GPU : %s\n", get_gpu(*gpu));
fclose(f_cache);
printf("\n FILE CACHING DONE!!\n");
printf("Caching occurs only once,\n");
printf("every subsequent execution will\n");
printf("run program normally. Enjoy!\n\n");
cache_info(cpu_name, gpu);
}
free(cache_path);
}
static int count_files(DIR *package_dir) {
struct dirent * entry;
int file_count = 0;
while ((entry = readdir(package_dir)) != NULL) {
if (entry->d_type == DT_DIR) {
file_count++;
}
}
closedir(package_dir);
return file_count;
}
static char *get_sys(char *s_os, char *os_name) {
char *name = malloc(BUF_SIZE);
FILE *f_sys_name = fopen("/etc/issue", "rt");
os_name = malloc(BUF_SIZE);
if( f_sys_name == NULL ){
fprintf(stderr, "\nCan't get os name\n");
exit(EXIT_FAILURE);
}
fscanf(f_sys_name, "%s %*s", name);
fclose(f_sys_name);
truncate_spaces(name);
sys = *(strstr(OS_TABLE, name) - 2);
logo_number = (int) (strchr(s_os, sys) - s_os);
if( sys == 'r' )
snprintf(os_name, BUF_SIZE, "\x1b[36mOS\x1b[0m -> %s", name); // Arco has a retarded name to be honest, without a space
else
snprintf(os_name, BUF_SIZE, "\x1b[36mOS\x1b[0m -> %s Linux", name);
free(name);
return os_name;
}
static char *get_cpu(char *cpu_name){
char *line = malloc(BUF_SIZE * 4);
cpu_name = malloc(BUF_SIZE * 4);
FILE *cpu = fopen("/proc/cpuinfo", "rt");
if( cpu == NULL ){
printf("\nCan't get cpu info\n");
exit(EXIT_FAILURE);
}
// Skip first four lines, cpu info is on fifth
for(int i = 0; i < 5; i++)
fgets(line, BUF_SIZE * 4, cpu);
snprintf(cpu_name, BUF_SIZE * 4, "%s", strchr(line, ':') +2);
truncate_spaces(cpu_name);
fclose(cpu);
free(line);
return cpu_name;
}
static char *get_gpu(char *gpu){
gpu = malloc(BUF_SIZE);
// https://github.com/pciutils/pciutils/blob/master/example.c
char buffer[BUF_SIZE];
struct pci_access * pacc = pci_alloc();
pci_init(pacc);
pci_scan_bus(pacc);
struct pci_dev * dev = pacc -> devices;
while (dev) {
pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS);
if (dev -> device_class == 768) {
break;
}
dev = dev -> next;
}
char * model = pci_lookup_name(pacc, buffer, sizeof(buffer), PCI_LOOKUP_DEVICE, dev -> vendor_id, dev -> device_id);
pci_cleanup(pacc);
char * vendor = "unknown vendor";
switch(dev -> vendor_id){
case 4098:
vendor = "AMD";
break;
case 4318:
vendor = "NVIDIA";
break;
case 32902:
vendor = "Intel";
break;
}
snprintf(gpu, BUF_SIZE, "%s %s", vendor, model);
return gpu;
}
static char *get_kernel(char *kern_name){
kern_name = malloc(BUF_SIZE);
struct utsname u_info;
uname(&u_info);
snprintf(kern_name, BUF_SIZE, "\x1b[36mKERN\x1b[0m -> Linux %s", u_info.release);
return kern_name;
}
static char *get_uptime(char *uptime){
uptime = malloc(BUF_SIZE);
unsigned int sec;
short hr, min;
struct sysinfo sys_info;
sysinfo(&sys_info);
sec = sys_info.uptime;
hr = (sec/60/60%24);
min = (sec/60%60);
snprintf(uptime, BUF_SIZE, "\x1b[36mUPT\x1b[0m -> %hd h, %hd min", hr, min);
return uptime;
}
static char *get_packages(char *package_count){
int pkg_count = 0;
package_count = malloc(BUF_SIZE);
if( strchr(ARCH_BASED, sys) )
pkg_count = count_files(opendir("/var/lib/pacman/local"));
else if( strchr(DEBIAN_BASED, sys) )
pkg_count = count_files(opendir("/usr/bin")) + count_files(opendir("/sbin")); // still not sure where to look
else{
printf("\n\n\aUnable to find package list\n\n");
exit(EXIT_FAILURE);
}
snprintf(package_count, BUF_SIZE, "\x1b[36mPKGS\x1b[0m -> %d", pkg_count);
return package_count;
}
static char *get_RAM(char *ram_info){
int bar_percent;
float total,
free_mem,
used,
real_percent;
ram_info = malloc(BUF_SIZE * 3);
char *line = malloc(BUF_SIZE * 3),
bar[] = "[----------]";
FILE *RAM = fopen("/proc/meminfo", "rt");
// Get total amount of RAM
fgets(line, BUF_SIZE * 3, RAM);
truncate_spaces(line);
sscanf(line, " MemTotal: %f", &total);
// throw away second line of file
fgets(line, BUF_SIZE * 3, RAM);
// Get free memory
fgets(line, BUF_SIZE * 3, RAM);
truncate_spaces(line);
sscanf(line, " MemAvailable: %f", &free_mem);
fclose(RAM);
used = total - free_mem;
real_percent = (used / total) * 100;
bar_percent = (real_percent / 10 + 0.25);
for(int i = 1; i <= bar_percent; i++){
bar[i] = '*';
}
snprintf(ram_info, BUF_SIZE * 3, "\x1b[36mRAM\x1b[0m -> %.2f GB of %.2f GB, %s -> %.2f %%", used / 1000000,
total / 1000000,
bar, real_percent);
free(line);
return ram_info;
}
void concatenate_print(char *os, char *cpu_name, char *gpu){
char *uptime = NULL,
*kern_name = NULL,
*ram_info = NULL,
*package_count = NULL;
strcat( (logo + logo_number)->logo[0], os);
strcat( (logo + logo_number)->logo[1], get_kernel(kern_name));
strcat( (logo + logo_number)->logo[2], get_uptime(uptime));
strcat( (logo + logo_number)->logo[3], get_packages(package_count));
strcat( (logo + logo_number)->logo[4], cpu_name);
strcat( (logo + logo_number)->logo[5], gpu);
strcat( (logo + logo_number)->logo[6], get_RAM(ram_info));
printf("\n");
for(int i = 0; i < COLS ; i++)
printf("%s\n", (logo + logo_number)->logo[i]);
free(uptime);
free(ram_info);
free(package_count);
free(kern_name);
}

78
logos.h
View file

@ -1,78 +0,0 @@
typedef struct s_logos {
char logo[COLS][ROWS];
} t_logos;
t_logos logo[6] = {
{ "\x1b[1m /\\ ",
"\x1b[1m / \\ ",
"\x1b[1m /`'.,\\ ",
"\x1b[1m / ', ",
"\x1b[1m / ,`\\ ",
"\x1b[1m / ,.'`. \\ ",
"\x1b[1m /.,'` `'.\\ "
},
{ "\x1b[1m . ",
"\x1b[1m / \\ ",
"\x1b[1m / \\ ",
"\x1b[1m /^. \\ ",
"\x1b[1m / .-. \\ ",
"\x1b[1m / ( ) _\\ ",
"\x1b[1m / _.~ ~._^\\ ",
"\x1b[1m /.^ ^.\\ "
},
{ "\x1b[1m _____ ",
"\x1b[1m / __ \\ ",
"\x1b[1m | / | ",
"\x1b[1m | \\___- ",
"\x1b[1m -_ ",
"\x1b[1m --_ ",
"\x1b[1m "
},
{ "\x1b[1m _ ",
"\x1b[1m ---(_) ",
"\x1b[1m _/ --- \\ ",
"\x1b[1m (_) | | ",
"\x1b[1m \\ --- / ",
"\x1b[1m ---(_) ",
"\x1b[1m "
},
{ "\x1b[1m /\\ ",
"\x1b[1m / \\ ",
"\x1b[1m / /\\ \\ ",
"\x1b[1m / / \\ \\ ",
"\x1b[1m / / \\ \\ ",
"\x1b[1m / / _____\\ \\ ",
"\x1b[1m /_/ \\`----.\\_\\ "
},
{ "\x1b[1m ||||||||| |||| ",
"\x1b[1m ||||||||| |||| ",
"\x1b[1m |||| |||| ",
"\x1b[1m |||| |||| |||| ",
"\x1b[1m |||| |||| |||| ",
"\x1b[1m |||| |||| |||| ",
"\x1b[1m |||| |||| |||| "
}
};

296
minchy.c Normal file
View file

@ -0,0 +1,296 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <unistd.h>
#include <sys/statvfs.h>
#define BUF_SIZE 50
#define SUPPORTED_OS "xadurm"
#define ARCH_BASED "axmr"
#define DEBIAN_BASED "du"
#define OS_TABLE "a:Arch|x:Artix|r:Arco|m:Manjaro|u:Ubuntu|d:Debian"
void read_line(char x);
static int count_files(DIR *package_dir);
static char *get_sys(void);
static char *get_kernel(void);
static char *get_uptime(void);
static char *get_RAM(void);
static char *get_packages(void);
static char *get_term(void);
char sys;
Display *display;
int main(){
printf("\n");
printf(" %s\n", get_sys());
printf(" %s\n", get_kernel());
printf(" %s\n", get_uptime());
printf(" %s\n", get_packages());
printf(" \x1b[37m \x1b[0m %s\n", get_term());
printf(" %s\n", get_RAM());
printf("\n");
return EXIT_SUCCESS;
}
void read_line(char x) {
int c;
while (( c = getchar()) != x && c != EOF) {}
}
void truncate_spaces(char *str) {
int src = 0, dst = 0, index, i = -1;
while(*(str + dst) == ' ') dst++;
while(*(str + dst) != '\0') {
*(str + src) = *(str + dst);
if(*(str + (dst++)) == ' ')
while(*(str + dst) == ' ') dst++;
src++;
}
*(str + src) = '\0';
i = 0;
while(str[i] != '\0'){
if(str[i] != ' ' && str[i] != '\t' && str[i] != '\n'){
index= i;
}
i++;
}
str[index + 1] = '\0';
}
static int count_files(DIR *package_dir) {
struct dirent * entry;
int file_count = 0;
while ((entry = readdir(package_dir)) != NULL) {
if (entry->d_type == DT_DIR) {
file_count++;
}
}
closedir(package_dir);
return file_count;
}
static char *get_sys(void) {
char *name = malloc(BUF_SIZE);
FILE *f_sys_name = fopen("/etc/issue", "rt");
char *os_name = malloc(BUF_SIZE);
if( f_sys_name == NULL ){
fprintf(stderr, "\nCan't get os name\n");
exit(EXIT_FAILURE);
}
fscanf(f_sys_name, "%s %*s", name);
fclose(f_sys_name);
truncate_spaces(name);
if( !(sys = *(strstr(OS_TABLE, name) - 2)) ){
fprintf(stderr, "\nUnsupported OS\n");
exit(EXIT_FAILURE);
}
snprintf(os_name, BUF_SIZE, "\x1b[37m \x1b[0m %s", name);
free(name);
return os_name;
}
static char *get_kernel(void){
char *kern_name = malloc(BUF_SIZE);
struct utsname u_info;
uname(&u_info);
snprintf(kern_name, BUF_SIZE, "\x1b[37m \x1b[0m %s", u_info.release);
return kern_name;
}
static char *get_uptime(void){
char *uptime = malloc(BUF_SIZE);
unsigned int sec;
short hr, min;
struct sysinfo sys_info;
sysinfo(&sys_info);
sec = sys_info.uptime;
hr = (sec/60/60%24);
min = (sec/60%60);
snprintf(uptime, BUF_SIZE, "\x1b[37m \x1b[0m %hd h, %hd min", hr, min);
return uptime;
}
static char *get_packages(void){
int pkg_count = 0;
char *package_count = malloc(BUF_SIZE);
if( strchr(ARCH_BASED, sys) )
pkg_count = count_files(opendir("/var/lib/pacman/local"));
else if( strchr(DEBIAN_BASED, sys) )
pkg_count = count_files(opendir("/usr/bin")) + count_files(opendir("/sbin")); // still not sure where to look
else{
printf("\n\n\aUnable to find package list\n\n");
exit(EXIT_FAILURE);
}
snprintf(package_count, BUF_SIZE, "\x1b[37m \x1b[0m %d", pkg_count);
return package_count;
}
static char *get_RAM(void){
float used_m, total_m;
int total, shared, memfree, buffers, cached, reclaimable;
char *ram_info = malloc(BUF_SIZE * 3);
FILE *RAM = fopen("/proc/meminfo", "rt");
char *line = NULL;
size_t len;
while (getline(&line, &len, RAM) != -1) {
sscanf(line, "MemTotal: %d", &total);
sscanf(line, "Shmem: %d", &shared);
sscanf(line, "MemFree: %d", &memfree);
sscanf(line, "Buffers: %d", &buffers);
sscanf(line, "Cached: %d", &cached);
sscanf(line, "SReclaimable: %d", &reclaimable);
}
fclose(RAM);
free(line);
used_m = (float)(total + shared - memfree - buffers - cached - reclaimable) / (1024*1024);
total_m = (float)total / (1024*1024);
snprintf(ram_info, BUF_SIZE * 3, "\x1b[37m \x1b[0m %.2f / %.2f GB", used_m, total_m);
return ram_info;
}
static char *get_term(void) {
unsigned char *prop;
char *terminal = malloc(BUF_SIZE);
if (display != NULL) {
unsigned long _,
window = RootWindow(display, XDefaultScreen(display));
Atom a,
active = XInternAtom(display, "_NET_ACTIVE_WINDOW", True),
class = XInternAtom(display, "WM_CLASS", True);
#define GetProp(property) \
XGetWindowProperty(display, window, property, 0, 64, 0, 0, &a, (int *)&_, &_, &_, &prop);
GetProp(active);
window = (prop[3] << 24) + (prop[2] << 16) + (prop[1] << 8) + prop[0];
free(prop);
if(!window) goto terminal_fallback;
GetProp(class);
#undef GetProp
snprintf(terminal, BUF_SIZE, "%s", prop);
free(prop);
}
else {
terminal_fallback:
strncpy(terminal, getenv("TERM"), BUF_SIZE);
if (strcmp(terminal, "linux") == 0) {
strncpy(terminal, ttyname(STDIN_FILENO), BUF_SIZE);
}
}
return terminal;
}