#pragma GCC diagnostic ignored "-Wunused-function" #include #include #include #include #include #include #include #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" //ascii art header file #include "logos.h" // standardish functions void read_line(char x); void cache_info(char **cpu_name, char **gpu, char *os_table); static int count_files(DIR *package_dir); // 'get info' functions static char *get_sys(char *s_os, char *os_name, char *os_table); 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, *os = malloc(BUF_SIZE), *os_table = malloc(BUF_SIZE * 2), *s_os = SUPPORTED_OS; // if cache file exits, read it, otherwise cache info cache_info(&cpu_name, &gpu, os_table); os = get_sys(s_os, os_name, os_table); // chack 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); 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 *os_table) { 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); //get OS table fgets(os_table, BUF_SIZE * 2, f_cache); 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)); fprintf(f_cache, "a:Arch|x:Artix|r:Arco|m:Manjaro|u:Ubuntu|d:Debian\n"); 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, os_table); } 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 *os_table) { os_name = malloc(BUF_SIZE); char *name = malloc(BUF_SIZE); FILE *f_sys_name = fopen("/etc/issue", "rt"); 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); }