#include #include #include #include #include #include #include #include #include "sorting.h" #include "defines.h" #include "config.h" extern dir mid_dir; extern unsigned int settings; extern unsigned int file_modifiers; extern unsigned int color_count; extern unsigned int terminal_height; extern volatile unsigned long selected_file_current; extern volatile unsigned long selected_file_last; extern color *colors; int (*order_func)() = sort_natural; linked_dir *visited_dirs; linked_dir *current_dir; unsigned long get_dir_size(char *path){ DIR *dir = opendir(path); unsigned long entry_count = 0; struct dirent *entry; if (dir && file_modifiers & FILE_MODIFIERS_HIDDEN_FILES) { while ((entry=readdir(dir))) { entry_count++; } /* removes files "." and ".." */ entry_count -= 2; } else if (dir) { while ((entry=readdir(dir))) { if (entry->d_name[0] != '.') { entry_count++; } } } closedir(dir); return entry_count; } void get_dir_content(char *path, dir *dir){ struct dirent **entry = NULL; if (file_modifiers & FILE_MODIFIERS_HIDDEN_FILES) { /* print hidden files */ scandir(path, &entry, skip_dot, NULL); } else { scandir(path, &entry, skip_hidden_files, NULL); } char *full_path = NULL; unsigned long i = 0; for (i = 0; i < dir->file_count; i++ ) { dir->file_list[i].file_name = NULL; if (entry[i]->d_name[0] == '.' && !(file_modifiers & FILE_MODIFIERS_HIDDEN_FILES)) { } else { dir->file_list[i].file_name = malloc(strlen(entry[i]->d_name)+1); memcpy(dir->file_list[i].file_name, entry[i]->d_name, strlen(entry[i]->d_name) + 1); dir->file_list[i].status = 0; struct stat *file; file = malloc(sizeof(struct stat)); /* using the full path allows using the same function for all windows */ full_path = malloc(strlen(path) + strlen(entry[i]->d_name) + 1 + sizeof("/")); memcpy(full_path, path, strlen(path)); memcpy(full_path + strlen(path) + sizeof("/") - 1, entry[i]->d_name, strlen(entry[i]->d_name) + 1); full_path[strlen(path)] = '/'; lstat(full_path, file); dir->file_list[i].file_size = file->st_size; dir->file_list[i].permissions = file->st_mode; if (S_ISLNK(file->st_mode)) { stat(full_path, file); if (S_ISDIR(file->st_mode)) { dir->file_list[i].file_type = FILE_TYPE_DIR | FILE_TYPE_SYMLINK; dir->file_list[i].color_pair = COLOR_SYMLINK; dir->file_list[i].file_size = get_dir_size(full_path); } else { dir->file_list[i].file_type = FILE_TYPE_REGULAR | FILE_TYPE_SYMLINK; dir->file_list[i].color_pair = COLOR_SYMLINK; } } else if (S_ISDIR(file->st_mode)) { dir->file_list[i].file_type = FILE_TYPE_DIR; dir->file_list[i].color_pair = COLOR_DIR; dir->file_list[i].file_size = get_dir_size(full_path); } else if (file->st_mode & S_IXUSR) { dir->file_list[i].file_type = FILE_TYPE_EXEC; dir->file_list[i].color_pair = COLOR_EXEC; } else if (S_ISREG(file->st_mode)) { dir->file_list[i].file_type = FILE_TYPE_REGULAR; dir->file_list[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->file_list[i].color_pair = colors[j].color_pair; } } } } else if (S_ISBLK(file->st_mode)) { dir->file_list[i].file_type = FILE_TYPE_BLOCK; dir->file_list[i].color_pair = COLOR_BLOCK; } else if (S_ISCHR(file->st_mode)) { dir->file_list[i].file_type = COLOR_CHARDEV; } else if (S_ISFIFO(file->st_mode)) { dir->file_list[i].file_type = FILE_TYPE_FIFO; dir->file_list[i].color_pair = COLOR_FIFO; } else if (S_ISSOCK(file->st_mode)) { dir->file_list[i].file_type = FILE_TYPE_SOCK; dir->file_list[i].color_pair = COLOR_SOCK; } else { dir->file_list[i].file_type = COLOR_REGULAR; dir->file_list[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->file_list[i].color_pair = colors[j].color_pair; } } } else { } } free(full_path); free(file); free(entry[i]); full_path = NULL; file = NULL; entry[i] = NULL; } } qsort(dir->file_list, dir->file_count, sizeof(file), order_func); free(entry); } void print_dir(WINDOW *win, char print_info, dir *dir){ /* i am not proud of this function */ unsigned long line_width = getmaxx(win); unsigned long i = 0; float file_size; float printed_size = 0; char size_char = ' '; char is_selected = 0; unsigned long offset_vertical = 0; unsigned long offset_back = 0; #if SETTINGS_LINE_NUMBERS == 0 unsigned long offset_front = 0; #else long offset_front = 2; #endif long selected_file_current = dir->current_file - dir->file_list; long offset_index = 2; /* only used for the index of the file itself */ if (print_info) { if (dir->file_count > 9) { #if SETTINGS_LINE_NUMBERS != 0 unsigned long dir_file_count_ = dir->file_count; while(dir_file_count_ > 9) { offset_front++; dir_file_count_ /= 10; } #endif } if (selected_file_current > (terminal_height/3)*2 && dir->file_count > terminal_height - 2) { if (selected_file_current + (terminal_height/3) >= dir->file_count) { offset_vertical = dir->file_count - terminal_height+2; } else { offset_vertical = selected_file_current - (terminal_height/3)*2; } } } else { offset_front = 0; } for (i = offset_vertical; i < dir->file_count && i < (terminal_height + offset_vertical); i++) { if (print_info) { file_size = dir->file_list[i].file_size; char size_index = -1; do { printed_size=file_size; file_size /= 1024; size_index++; } while (file_size > 1 && size_index < size_unit_count); size_char = size_unit[(unsigned)size_index]; if (dir->file_list[i].file_type &= FILE_TYPE_DIR) { offset_back = line_width - (snprintf(NULL,0,"%ld", dir->file_list[i].file_size) + 1); } else if (size_char =='B') { offset_back = line_width - (snprintf(NULL,0,"%0.0lf %c", printed_size, size_char) + 1); } else { offset_back = line_width - (snprintf(NULL,0,"%0.2lf %c", printed_size, size_char) + 1); } } else { offset_back = line_width; } if (dir->file_list[i].status & FILE_STATUS_SELECTED) { is_selected = 1; } else { is_selected = 0; } if (dir->file_list[i].status & FILE_STATUS_SELECTED) { wattron(win, COLOR_PAIR(8)); } else { wattron(win, COLOR_PAIR(dir->file_list[i].color_pair)); } if (&dir->file_list[i] == dir->current_file) { wattron(win, A_REVERSE); unsigned long bg = 0; for (bg = 0; bg < line_width; bg++) { mvwaddch(win, i-offset_vertical, bg, ' '); } } else { wattroff(win, A_REVERSE); } if(print_info) { #if SETTINGS_LINE_NUMBERS == 2 long i_ = (selected_file_current) - i; offset_index = 0; while(i_) { offset_index++; i_ /= 10; } long relative_index = selected_file_current - i; if (relative_index < 0) { relative_index = relative_index * -1; } else if (relative_index == 0) { i_ = (selected_file_current != 0) ? (selected_file_current) : 1; while(i_) { offset_index++; i_ /= 10; } relative_index = i; } mvwprintw(win, i-offset_vertical, offset_front-offset_index-1, "%ld", relative_index); #elif SETTINGS_LINE_NUMBERS == 1 unsigned long i_ = i; offset_index = 2; while(i_ > 9) { offset_index++; i_ /= 10; } mvwprintw(win, i-offset_vertical, offset_front-offset_index, "%ld", i); #endif if (dir->file_list[i].file_type &= FILE_TYPE_DIR) { mvwprintw(win, i-offset_vertical, offset_back, "%ld", dir->file_list[i].file_size); }else if (size_char =='B') { mvwprintw(win, i-offset_vertical, offset_back, "%0.0lf %c", printed_size, size_char); } else { mvwprintw(win, i-offset_vertical, offset_back, "%0.2lf %c", printed_size, size_char); } } char *extension = strrchr(dir->file_list[i].file_name, '.'); unsigned long printable_size = offset_back-offset_front-is_selected-2; mvwaddnstr(win, i-offset_vertical, offset_front+is_selected, dir->file_list[i].file_name, printable_size); if (extension && printable_size <= strlen(dir->file_list[i].file_name)) { mvwaddnstr(win, i-offset_vertical, offset_back-strlen(extension)-1, extension, strlen(extension)); mvwaddnstr(win, i-offset_vertical, offset_back-strlen(extension)-2, "~", 1); } if (dir->file_list[i].status & FILE_STATUS_SELECTED) { wattroff(win, COLOR_PAIR(8)); } else { wattroff(win, COLOR_PAIR(dir->file_list[i].color_pair)); } } } char update_selected_file(){ char ret = -1; /* -1 on empty or inaccessible file, 0 on unchanged file, 1 on changed file */ /* if (selected_file_current >= mid_file_count) { selected_file_current = mid_file_count-1; } if (selected_file_current != selected_file_last && selected_file_last <= mid_file_count) { mid_content[selected_file_last].status &= ~FILE_STATUS_HOVER; ret = 1; } else { ret = 0; } mid_dir.current_dir.status |= FILE_STATUS_HOVER; selected_file_last = selected_file_current; */ return ret; } void dir_set_selected_file_current(unsigned long selected_file_current){ /* if (mid_content->file_name) { current_dir->selected_file_current = selected_file_current; } */ } unsigned long dir_get_selected_file_current(){ /* current_dir = visited_dirs; if (mid_content->file_name[0] == '\0') { return 0; } char hit = 0; char *path = getcwd(NULL, 0); while(current_dir->next != NULL) { if (strcmp(path, current_dir->path) == 0) { hit = 1; break; } current_dir = current_dir->next; } if (hit == 0) { current_dir->next = malloc(sizeof(linked_dir)); current_dir->next->next = NULL; current_dir->next->path = path; return 0; } else { free(path); return current_dir->selected_file_current; } */ } void dir_init(){ visited_dirs = malloc(sizeof(linked_dir)); visited_dirs->path = getcwd(NULL, 0); visited_dirs->selected_file_current = 0; visited_dirs->next = NULL; current_dir = visited_dirs; } void recursive_delete(file current_file){ /* if (S_ISLNK(current_file.permissions)) { remove(current_file.file_name); } else if (current_file.file_type & FILE_TYPE_DIR ) { unsigned int file_modifiers_tmp = file_modifiers; file_modifiers |= FILE_MODIFIERS_HIDDEN_FILES; unsigned long current_file_count = get_dir_size(current_file.file_name); if (current_file_count != 0) { file *current_dir = malloc(current_file_count * sizeof(file)); memset(current_dir, '\0', current_file_count * sizeof(file)); get_dir_content(current_file.file_name, ¤t_file_count, current_dir); if (chdir(current_file.file_name) != 0) { return; } unsigned long i; for (i = 0; i < current_file_count; i++) { recursive_delete(current_dir[i]); free(current_dir[i].file_name); } free(current_dir); if (chdir("..") != 0) { return; } } remove(current_file.file_name); file_modifiers = file_modifiers_tmp; } else { remove(current_file.file_name); } */ }