Compare commits

...

4 Commits

Author SHA1 Message Date
nova
7f0e65eaf3 improvenment to color managenment 2025-05-10 23:33:27 +02:00
nova
882e6fc85f added colors.h to repo 2025-05-10 22:39:14 +02:00
nova
6617b3fe4e added natural sort 2025-05-10 22:30:52 +02:00
nova
d4a4f5ebb2 parsing of /etc/DIR_COLORS 2025-05-10 21:51:09 +02:00
7 changed files with 249 additions and 25 deletions

View File

@ -39,6 +39,7 @@ void get_dir_content(char *path, unsigned long *dir_file_count, file *dir_conten
scandir(path, &entry, skip_hidden_files, alphasort);
}
unsigned long i = 0;
for (i = 0; i < *dir_file_count; i++ ) {
if (entry[i]->d_name[0] == '.' && !(file_modifiers & FILE_MODIFIERS_HIDDEN_FILES)) {
@ -53,35 +54,56 @@ void get_dir_content(char *path, unsigned long *dir_file_count, file *dir_conten
lstat(dir_content[i].file_name, file);
if (S_ISDIR(file->st_mode)) {
dir_content[i].file_type = COLOR_DIR;
dir_content[i].file_type = FILE_TYPE_DIR;
dir_content[i].color_pair = COLOR_DIR;
} else if (file->st_mode & S_IXUSR) {
dir_content[i].file_type = FILE_TYPE_EXEC;
dir_content[i].color_pair = COLOR_EXEC;
} else if (S_ISBLK(file->st_mode)) {
dir_content[i].file_type = COLOR_BLOCK;
} else if (S_ISCHR(file->st_mode)) {
dir_content[i].file_type = COLOR_CHARDEV;
dir_content[i].file_type = FILE_TYPE_BLOCK;
dir_content[i].color_pair = COLOR_BLOCK;
/*} else if (S_ISCHR(file->st_mode)) {
dir_content[i].file_type = COLOR_CHARDEV; */
} else if (S_ISLNK(file->st_mode)) {
dir_content[i].file_type = COLOR_SYMLINK;
dir_content[i].file_type = FILE_TYPE_SYMLINK;
dir_content[i].color_pair = COLOR_SYMLINK;
} else if (S_ISFIFO(file->st_mode)) {
dir_content[i].file_type = COLOR_FIFO;
dir_content[i].file_type = FILE_TYPE_FIFO;
dir_content[i].color_pair = COLOR_FIFO;
} else if (S_ISSOCK(file->st_mode)) {
dir_content[i].file_type = COLOR_SOCK;
dir_content[i].file_type = FILE_TYPE_SOCK;
dir_content[i].color_pair = COLOR_SOCK;
} else if (S_ISREG(file->st_mode)) {
dir_content[i].file_type = COLOR_REGULAR;
dir_content[i].file_type = FILE_TYPE_REGULAR;
dir_content[i].color_pair = COLOR_REGULAR;
unsigned long j = 0;
char *extension = strrchr(entry[i]->d_name, '.');
if (extension) {
for (j = 0; j < color_count; j++) {
if (!strcmp(colors[j].file_extension, extension)) {
dir_content[i].file_type = colors[j].color_pair;
dir_content[i].color_pair = colors[j].color_pair;
}
}
} else {
}
} else {
dir_content[i].file_type = COLOR_REGULAR;
dir_content[i].color_pair = COLOR_REGULAR;
unsigned long j = 0;
char *extension = strrchr(entry[i]->d_name, '.');
if (extension) {
for (j = 0; j < color_count; j++) {
if (!strcmp(colors[j].file_extension, extension)) {
dir_content[i].color_pair = colors[j].color_pair;
}
}
} else {
}
}
free(file);
}
}
qsort(dir_content, *dir_file_count, sizeof(file), sort_natural);
for (i = 0; i < *dir_file_count; i++) {
free(entry[i]);
@ -94,9 +116,15 @@ void print_dir(WINDOW *win, unsigned long *dir_file_count, file *dir_content){
unsigned long i = 0;
for (i = 0; i < *dir_file_count; i++) {
wattron(win, COLOR_PAIR(dir_content[i].file_type));
mvwprintw(win, i, 0, "%d", dir_content[i].file_type);
wattron(win, COLOR_PAIR(dir_content[i].color_pair));
if (dir_content[i].status & FILE_STATUS_HOVER) {
wattron(win, A_REVERSE);
}
mvwprintw(win, i, 0, "%d", dir_content[i].color_pair);
mvwaddstr(win, i, 3,dir_content[i].file_name);
wattroff(win, COLOR_PAIR(dir_content[i].file_type));
if (dir_content[i].status & FILE_STATUS_HOVER) {
wattroff(win, A_REVERSE);
}
wattroff(win, COLOR_PAIR(dir_content[i].color_pair));
}
}

145
colors.c Normal file
View File

@ -0,0 +1,145 @@
#define _POSIX_C_SOURCE 200809L
#include <bits/types/FILE.h>
#include <stdio.h>
#include <curses.h>
#include <string.h>
#include "defines.h"
unsigned int color_count;
color *colors;
extern file *rgt_content;
extern unsigned long rgt_file_count;
extern unsigned int settings;
extern unsigned int status;
void parse_colors(char *line, short *fg, short *bg){
int tmp;
/* cuts everything before the space, then uses ';' as the token delimeter */
char *token = strtok(strrchr(line, ' '), ";");
while (token != NULL) {
sscanf(token, "%d", &tmp);
/* magic numbers are ansi color codes */
if ( tmp > 29 && tmp < 38) {
*fg = tmp - 30;
} else if ( tmp > 39 && tmp < 48) {
*bg = tmp - 40;
}
token = strtok(NULL, ";");
}
}
void colors_init() {
if (has_colors()) {
settings |= SETTINGS_HAS_COLOR;
start_color();
color_count = 0;
init_pair(0, COLOR_WHITE, COLOR_BLACK); /* unknown file */
if (status & STATUS_USER_ROOT) {
init_pair(10, COLOR_RED, COLOR_BLACK); /* path */
} else {
init_pair(10, COLOR_GREEN, COLOR_BLACK); /* path */
}
FILE *dircolors = fopen("/etc/DIR_COLORS", "r");
if (dircolors) {
char *line;
char *token;
char *extension;
int tmp = 0;
size_t size = 0;
short fg;
short bg;
char supported_filetype_count = 9;
char initial_pass = 0;
while ((tmp = getline(&line, &size, dircolors)) != -1 && initial_pass != supported_filetype_count) {
fg = 7;
bg = 0;
token = strtok(line, " ");
if (token[0] != '#' && token[0] != '\n') {
if (!strcmp(token, "DIR")) {
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(1, fg, bg); /* directory */
} else if (!strcmp(token, "EXEC")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(2, fg, bg); /* exec */
} else if (!strcmp(token, "RESET")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(3, fg, bg); /* regular file */
} else if (!strcmp(token, "LINK")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(4, fg, bg); /* symlink */
} else if (!strcmp(token, "BLK")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(5, fg, bg); /* block device */
} else if (!strcmp(token, "CHR")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(6, fg, bg); /* character device */
} else if (!strcmp(token, "SOCK")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(7, fg, bg); /* socket */
} else if (!strcmp(token, "FIFO")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(8, fg, bg); /* fifo */
} else if (!strcmp(token, "ORPHAN")){
initial_pass++;
parse_colors(line, &fg, &bg);
init_pair(9, fg, bg); /* orphan */
}
}
}
/* checks for only extensions (*.[extension], includes the '.') as the filetypes are handled seperately */
while ((tmp = getline(&line, &size, dircolors)) != -1) {
if (line[0] == '.') {
color_count++;
}
}
rewind(dircolors);
colors = malloc(sizeof(color) * color_count);
unsigned int i = 0;
/* proper pass, reads all defined extensions within /etc/DIR_COLORS */
while ((tmp = getline(&line, &size, dircolors)) != -1) {
fg = 7;
bg = 0;
if (line[0] == '.') {
extension = strtok(line, " ");
colors[i].file_extension = malloc(sizeof(extension));
strcpy(colors[i].file_extension, extension);
colors[i].color_pair = i+11;
parse_colors(line, &fg, &bg);
init_pair(i+11, fg, bg);
i++;
}
}
} else {
init_pair(0, COLOR_WHITE, COLOR_BLACK); /* unknown file */
init_pair(1, COLOR_BLUE, COLOR_BLACK); /* directory */
init_pair(2, COLOR_WHITE, COLOR_BLACK); /* regular file */
init_pair(3, COLOR_YELLOW, COLOR_BLACK); /* symlink */
init_pair(4, COLOR_CYAN, COLOR_BLACK); /* block device */
init_pair(5, COLOR_YELLOW, COLOR_BLACK); /* character device */
init_pair(6, COLOR_MAGENTA, COLOR_BLACK); /* fifo */
init_pair(7, COLOR_YELLOW, COLOR_BLACK); /* socket */
init_pair(8, COLOR_BLACK, COLOR_BLUE); /* reserved */
}
}
}

3
colors.h Normal file
View File

@ -0,0 +1,3 @@
#include "colors.c"
void colors_init();

View File

@ -3,6 +3,7 @@
#define STATUS_UPDATE_SCREEN_MASK 12 /* 1100*/
#define STATUS_UPDATE_SCREEN_0 4
#define STATUS_UPDATE_SCREEN_RESIZE 8
#define STATUS_USER_ROOT 16
#define SETTINGS_HAS_COLOR 1
@ -16,22 +17,42 @@
#define FILE_MODIFIERS_SORT_REVERSE 64
/*FILE_MODIFIERS_SORT_NATURAL is when bitmask is 0*/
#define COLOR_REGULAR 0
#define FILE_STATUS_HOVER 1
#define FILE_STATUS_SELECTED 2;
#define FILE_STATUS_IS_REGULAR_FILE 4
#define COLOR_UNKNOWN 0
#define COLOR_DIR 1
#define COLOR_BLOCK 2
#define COLOR_CHARDEV 3
#define COLOR_EXEC 2 /* not really a filetype, moreso if it is executable */
#define COLOR_REGULAR 3
#define COLOR_SYMLINK 4
#define COLOR_FIFO 5
#define COLOR_SOCK 6
#define COLOR_PATH
#define COLOR_BLOCK 5
#define COLOR_CHARDEV 6
#define COLOR_SOCK 7
#define COLOR_FIFO 8
#define COLOR_ORPHAN 9
#define COLOR_PATH 10
#define FILE_TYPE_UNKNOWN COLOR_UNKNOWN
#define FILE_TYPE_DIR COLOR_DIR
#define FILE_TYPE_EXEC COLOR_EXEC
#define FILE_TYPE_REGULAR COLOR_REGULAR
#define FILE_TYPE_SYMLINK COLOR_SYMLINK
#define FILE_TYPE_BLOCK COLOR_BLOCK
#define FILE_TYPE_CHARDEV COLOR_CHARDEV
#define FILE_TYPE_SOCK COLOR_SOCK
#define FILE_TYPE_FIFO COLOR_FIFO
#define FILE_TYPE_ORPHAN COLOR_ORPHAN
#ifndef GUARD
#define GUARD
/* complex types are good actually */
typedef struct File {
char status;
char *file_name;
unsigned char file_type;
unsigned short color_pair;
unsigned long file_name_width;
unsigned long file_size_bytes;
} file;

4
main.c
View File

@ -2,6 +2,7 @@
#include <curses.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/sysinfo.h>
#include "threading.h"
#include "window.h"
@ -146,6 +147,9 @@ void init() {
/*file_modifiers = (FILE_MODIFIERS_HIDDEN_FILES | FILE_MODIFIERS_SORT_BITMASK);*/
status = (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK);
if (getuid() == 0) {
status += STATUS_USER_ROOT;
}
threading_init(); /* found in threading.c */
colors_init();

View File

@ -1,5 +1,6 @@
#include <curses.h>
#include <dirent.h>
#include <strings.h>
#include "defines.h"
extern unsigned int settings;
@ -12,3 +13,17 @@ int skip_hidden_files(const struct dirent *entry){
return 1;
}
int sort_natural(const void *file0, const void *file1){
unsigned char file_type0 = ((file*)file0)->file_type;
unsigned char file_type1 = ((file*)file1)->file_type;
if (file_type0 > file_type1) {
return 1;
} else if (file_type0 < file_type1) {
return -1;
} else {
char *file_name0 = ((file*)file0)->file_name;
char *file_name1 = ((file*)file1)->file_name;
return strcasecmp(file_name0, file_name1);
}
}

View File

@ -4,6 +4,9 @@
extern unsigned int status;
extern unsigned int color_count;
extern color *colors;
extern file *mid_content;
extern file *lft_content;
extern file *rgt_content;
@ -29,9 +32,9 @@ void window_top(WINDOW *win){
status |= STATUS_UPDATE_SCREEN_0;
} else {
for (i = 0; i < top_width; i++) {
mvwprintw(win, 0, i, "%c", top_content[i]);
}
wattron(win, COLOR_PAIR(COLOR_PATH));
mvwprintw(win, i, 0, "%s", top_content);
wattroff(win, COLOR_PAIR(COLOR_PATH));
pthread_mutex_unlock(&mutex_top);
}
}
@ -82,11 +85,16 @@ void window_rgt(WINDOW *win){
unsigned long local_height;
getmaxyx(win, local_height, local_width);
if (pthread_mutex_trylock(&mutex_rgt)) {
mvwprintw(win, local_height/2, local_width/2, "LOADING");
status |= STATUS_UPDATE_SCREEN_0;
} else {
/*
int i = 0;
for (i = 0; i < color_count; i++) {
wattron(win, COLOR_PAIR(colors[i].color_pair));
mvwprintw(win, i, 0, "%d", colors[i].color_pair);
mvwaddstr(win, i, 3,colors[i].file_extension);
wattroff(win, COLOR_PAIR(colors[i].color_pair));
}
pthread_mutex_unlock(&mutex_rgt);
mvwprintw(win, local_height/2, local_width/2, "%ld %ld", rgt_length_width[0], rgt_length_width[1]);
print_dir(win, rgt_length_width, rgt_file_name_width, rgt_content);
*/
}
}