fetchy/minchy.c

297 lines
5.4 KiB
C

#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;
}