Compare commits

..

13 commits

6 changed files with 181 additions and 134 deletions

View file

@ -55,18 +55,20 @@ t: go to trash dir
-: go to previous dir -: go to previous dir
z: refresh current dir z: refresh current dir
:: go to a directory by typing :: go to a directory by typing
u: sort files
.: toggle hidden files .: toggle hidden files
i: toggle file details
X: toggle executable
!: open shell in current dir
A: show directory disk usage/block size A: show directory disk usage/block size
i: toggle file details
u: sort files
x: view file/dir attributes
e: show history
y: copy filename to clipboard
!: open shell in current dir
f: new file f: new file
n: new dir n: new dir
r: rename r: rename
X: toggle executable
space: mark file space: mark file
a: mark all files in directory a: mark all files in directory
@ -82,10 +84,6 @@ O: open file with a GUI program detached from file manager
/: search /: search
x: view file/dir attributes
e: show history
y: copy filename to clipboard
c: copy c: copy
m: move m: move
s: symbolic link s: symbolic link

12
ccc.1
View file

@ -35,18 +35,20 @@ t: go to trash dir
-: go to previous dir -: go to previous dir
z: refresh current dir z: refresh current dir
:: go to a directory by typing :: go to a directory by typing
u: sort files
.: toggle hidden files .: toggle hidden files
i: toggle file details
X: toggle executable
!: open shell in current dir
A: show directory disk usage/block size A: show directory disk usage/block size
i: toggle file details
u: sort files
x: view file/dir attributes
e: show history
y: copy filename to clipboard
!: open shell in current dir
f: new file f: new file
n: new dir n: new dir
r: rename r: rename
X: toggle executable
space: mark file space: mark file
a: mark all files in directory a: mark all files in directory

251
ccc.c
View file

@ -53,7 +53,6 @@ void mkdir_p(const char *destdir);
void populate_files(const char *path, int ftype, ArrayList **list); void populate_files(const char *path, int ftype, ArrayList **list);
int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf); int get_directory_size(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
void add_file_stat(char *filename, char *path, int ftype); void add_file_stat(char *filename, char *path, int ftype);
char *get_file_mode(mode_t mode);
void list_files(void); void list_files(void);
void show_file_content(void); void show_file_content(void);
void edit_file(void); void edit_file(void);
@ -70,6 +69,8 @@ void create_file(void);
void delete_files(void); void delete_files(void);
void start_shell(void); void start_shell(void);
void yank_clipboard(void); void yank_clipboard(void);
void view_file_attr(void);
void show_history(void);
void wpprintw(const char *fmt, ...); void wpprintw(const char *fmt, ...);
void move_cursor(int row, int col); void move_cursor(int row, int col);
int readch(void); int readch(void);
@ -81,9 +82,9 @@ unsigned int focus = 0;
long sel_file = 0; long sel_file = 0;
int file_picker = 1; int file_picker = 1;
int to_open_file = 0; int to_open_file = 0;
char *argv_cp; char argv_cp[PATH_MAX];
char *cwd; char cwd[PATH_MAX];
char *p_cwd; /* previous cwd */ char p_cwd[PATH_MAX]; /* previous cwd */
int half_width; int half_width;
ArrayList *files; ArrayList *files;
ArrayList *marked; ArrayList *marked;
@ -114,7 +115,7 @@ int main(int argc, char **argv)
perror("ccc"); perror("ccc");
die("Error from chdir"); die("Error from chdir");
} else if (S_ISREG(st.st_mode)) { } else if (S_ISREG(st.st_mode)) {
argv_cp = estrdup(argv[1]); strcpy(argv_cp, argv[1]);
char *last_slash = strrchr(argv_cp, '/'); char *last_slash = strrchr(argv_cp, '/');
if (last_slash) { if (last_slash) {
*last_slash = '\0'; *last_slash = '\0';
@ -160,10 +161,7 @@ int main(int argc, char **argv)
marked = arraylist_init(100); marked = arraylist_init(100);
hashtable_init(); hashtable_init();
cwd = memalloc(PATH_MAX);
getcwd(cwd, PATH_MAX); getcwd(cwd, PATH_MAX);
p_cwd = memalloc(PATH_MAX);
p_cwd[0] = '\0';
populate_files(cwd, 0, &files); populate_files(cwd, 0, &files);
handle_sigwinch(-1); handle_sigwinch(-1);
@ -192,27 +190,27 @@ int main(int argc, char **argv)
break; break;
/* go back */ /* go back */
case BACKSPACE: case BACKSPACE:;
case ARROW_LEFT: case ARROW_LEFT:;
case 'h': case 'h':;
char dir[PATH_MAX];
strcpy(dir, cwd);
/* get parent directory */ /* get parent directory */
strcpy(p_cwd, cwd); char *last_slash = strrchr(dir, '/');
char *last_slash = strrchr(cwd, '/'); if (last_slash) {
if (last_slash != NULL) { if (!strcmp(last_slash, dir)) {
if (last_slash == cwd) {
change_dir("/", 0, 0); change_dir("/", 0, 0);
break; break;
} }
*last_slash = '\0'; *last_slash = '\0';
change_dir(cwd, 0, 0); change_dir(dir, 0, 0);
} }
break; break;
/* enter directory/open a file */ /* enter directory/open a file */
case ENTER: case ENTER:;
case ARROW_RIGHT: case ARROW_RIGHT:;
case 'l': case 'l':;
strcpy(p_cwd, cwd);
file c_file = files->items[sel_file]; file c_file = files->items[sel_file];
/* Check if it is directory or a regular file */ /* Check if it is directory or a regular file */
@ -279,10 +277,10 @@ int main(int argc, char **argv)
/* '~' go to $HOME */ /* '~' go to $HOME */
case TILDE:; case TILDE:;
char *home = getenv("HOME"); char *home = getenv("HOME");
if (home == NULL) { if (!home) {
wpprintw("$HOME not defined"); wpprintw("$HOME not defined (Press any key to continue)");
readch();
} else { } else {
strcpy(p_cwd, cwd);
change_dir(home, 0, 0); change_dir(home, 0, 0);
} }
break; break;
@ -290,9 +288,9 @@ int main(int argc, char **argv)
/* go to the trash dir */ /* go to the trash dir */
case 't':; case 't':;
char *trash_dir = check_trash_dir(); char *trash_dir = check_trash_dir();
if (trash_dir != NULL) { if (trash_dir) {
strcpy(p_cwd, cwd);
change_dir(trash_dir, 0, 0); change_dir(trash_dir, 0, 0);
free(trash_dir);
} }
break; break;
@ -364,6 +362,16 @@ int main(int argc, char **argv)
yank_clipboard(); yank_clipboard();
break; break;
case 'o':
case 'O':
case 'x':
view_file_attr();
break;
case 'e':
show_history();
break;
/* mark one file */ /* mark one file */
case SPACE: case SPACE:
add_file_stat(files->items[sel_file].name, files->items[sel_file].path, 1); add_file_stat(files->items[sel_file].name, files->items[sel_file].path, 1);
@ -429,8 +437,6 @@ void handle_sigwinch(int ignore)
void cleanup(void) void cleanup(void)
{ {
if (argv_cp != NULL)
free(argv_cp);
if (files->length != 0) { if (files->length != 0) {
arraylist_free(files); arraylist_free(files);
} }
@ -459,7 +465,7 @@ void show_help(void)
"\n\n?: show help\nq: exit with last dir written to file\n" "\n\n?: show help\nq: exit with last dir written to file\n"
"ctrl+c exit without writing last dir" "ctrl+c exit without writing last dir"
"\nPress any key to continue" "\nPress any key to continue"
); );
wpprintw("Visit https://github.com/night0721/ccc or use 'man ccc' for help"); wpprintw("Visit https://github.com/night0721/ccc or use 'man ccc' for help");
readch(); readch();
} }
@ -496,8 +502,18 @@ char *check_trash_dir(void)
*/ */
void change_dir(const char *buf, int selection, int ftype) void change_dir(const char *buf, int selection, int ftype)
{ {
if (cwd != buf) if (strcmp(cwd, buf) != 0) {
strcpy(cwd, buf); char tmp[PATH_MAX];
strcpy(tmp, buf);
strcpy(p_cwd, cwd);
strcpy(cwd, tmp);
char history_path[PATH_MAX];
strcpy(history_path, "~/.cache/ccc/history");
replace_home(history_path);
FILE *history_file = fopen(history_path, "a");
fprintf(history_file, "%s\n", cwd);
fclose(history_file);
}
if (ftype == 0) if (ftype == 0)
arraylist_free(files); arraylist_free(files);
chdir(cwd); chdir(cwd);
@ -511,12 +527,11 @@ void change_dir(const char *buf, int selection, int ftype)
*/ */
void mkdir_p(const char *destdir) void mkdir_p(const char *destdir)
{ {
char *path = memalloc(PATH_MAX); char path[PATH_MAX], dir_path[PATH_MAX];
char dir_path[PATH_MAX] = "";
if (destdir[0] == '~') { if (destdir[0] == '~') {
char *home = getenv("HOME"); char *home = getenv("HOME");
if (home == NULL) { if (!home) {
wpprintw("$HOME not defined"); wpprintw("$HOME not defined");
return; return;
} }
@ -531,7 +546,7 @@ void mkdir_p(const char *destdir)
dir_path[0] = '/'; dir_path[0] = '/';
char *token = strtok(path, "/"); char *token = strtok(path, "/");
while (token != NULL) { while (token) {
strcat(dir_path, token); strcat(dir_path, token);
strcat(dir_path, "/"); strcat(dir_path, "/");
@ -544,13 +559,10 @@ void mkdir_p(const char *destdir)
} }
wpprintw("mkdir failed: %s", strerror(errno)); wpprintw("mkdir failed: %s", strerror(errno));
free(path);
return; return;
} }
token = strtok(NULL, "/"); token = strtok(NULL, "/");
} }
free(path);
return; return;
} }
@ -563,13 +575,13 @@ void populate_files(const char *path, int ftype, ArrayList **list)
DIR *dp; DIR *dp;
struct dirent *ep; struct dirent *ep;
if ((dp = opendir(path)) != NULL) { if ((dp = opendir(path))) {
if (ftype == 0) { if (ftype == 0) {
tmp1 = arraylist_init(10); tmp1 = arraylist_init(10);
tmp2 = arraylist_init(10); tmp2 = arraylist_init(10);
} }
while ((ep = readdir(dp)) != NULL) { while ((ep = readdir(dp))) {
char *filename = estrdup(ep->d_name); char *filename = estrdup(ep->d_name);
/* Filter out dotfiles */ /* Filter out dotfiles */
@ -586,6 +598,7 @@ void populate_files(const char *path, int ftype, ArrayList **list)
if (ftype == 0) { if (ftype == 0) {
*list = arraylist_init(tmp1->length + tmp2->length); *list = arraylist_init(tmp1->length + tmp2->length);
(*list)->length = tmp1->length + tmp2->length; (*list)->length = tmp1->length + tmp2->length;
/* Need to see how to sort by date */
qsort(tmp1->items, tmp1->length, sizeof(file), sort_compare); qsort(tmp1->items, tmp1->length, sizeof(file), sort_compare);
qsort(tmp2->items, tmp2->length, sizeof(file), sort_compare); qsort(tmp2->items, tmp2->length, sizeof(file), sort_compare);
memcpy((*list)->items, tmp1->items, tmp1->length * sizeof(file)); memcpy((*list)->items, tmp1->items, tmp1->length * sizeof(file));
@ -622,29 +635,29 @@ void add_file_stat(char *filename, char *path, int ftype)
} }
int type; int type;
char *icon_str = memalloc(8); char icon_str[5];
filename[strlen(filename)] = '\0'; filename[strlen(filename)] = '\0';
/* handle file without extension /* handle file without extension
* ext is the extension if . exist in filename * ext is the extension if . exist in filename
* otherwise is nothing and handled through tenery operator */ * otherwise is nothing and handled through tenery operator */
char *ext = strrchr(filename, '.'); char *ext = strrchr(filename, '.');
if (ext != NULL) { if (ext) {
ext += 1; ext += 1;
} }
/* add file extension */ /* add file extension */
icon *ext_icon = hashtable_search(ext != NULL ? ext : filename); icon *ext_icon = hashtable_search(ext ? ext : filename);
if (ext_icon == NULL) if (!ext_icon)
memcpy(icon_str, "", 4); memcpy(icon_str, "", 4);
else else
memcpy(icon_str, ext_icon->icon, 5); memcpy(icon_str, ext_icon->icon, 4);
int color = DEF_COLOR; int color = DEF_COLOR;
if (S_ISDIR(file_stat.st_mode)) { if (S_ISDIR(file_stat.st_mode)) {
type = DRY; /* dir */ type = DRY; /* dir */
color = DIR_COLOR; color = DIR_COLOR;
memcpy(icon_str, "󰉋", 5); memcpy(icon_str, "󰉋", 4);
} else if (S_ISREG(file_stat.st_mode)) { } else if (S_ISREG(file_stat.st_mode)) {
type = REG; /* regular file */ type = REG; /* regular file */
color = REG_COLOR; color = REG_COLOR;
@ -677,7 +690,7 @@ void add_file_stat(char *filename, char *path, int ftype)
/* get last modified time */ /* get last modified time */
size_t time_size = 17; size_t time_size = 17;
char *time = memalloc(time_size); char time[time_size];
/* Format last modified time to a string */ /* Format last modified time to a string */
strftime(time, time_size, "%Y-%m-%d %H:%M", localtime(&file_stat.st_mtime)); strftime(time, time_size, "%Y-%m-%d %H:%M", localtime(&file_stat.st_mtime));
@ -694,10 +707,10 @@ void add_file_stat(char *filename, char *path, int ftype)
} }
} }
/* 4 before decimal + 1 dot + decimal_place (after decimal) + /* 4 before decimal + 1 dot + decimal_place (after decimal) +
unit length (1 for K, 3 for KiB, taking units[1] as B never changes) + 1 space + 1 null */ * unit length (1 for K, 3 for KiB, taking units[1] as B never changes) + 1 space + 1 null */
static const char* units[] = {"B", "K", "M", "G", "T", "P"}; static const char* units[] = {"B", "K", "M", "G", "T", "P"};
int size_size = 4 + 1 + decimal_place + strlen(units[1]) + 1 + 1; int size_size = 4 + 1 + decimal_place + strlen(units[1]) + 1 + 1;
char *size = memalloc(size_size); char size[size_size];
int unit = 0; int unit = 0;
while (bytes > 1024) { while (bytes > 1024) {
bytes /= 1024; bytes /= 1024;
@ -710,46 +723,33 @@ void add_file_stat(char *filename, char *path, int ftype)
sprintf(size, "%.*f%s", decimal_place, bytes, units[unit]); sprintf(size, "%.*f%s", decimal_place, bytes, units[unit]);
} }
/* get file mode string */ /* get file mode string */
char *mode_str = get_file_mode(file_stat.st_mode); char mode_str[11];
mode_str[0] = S_ISDIR(file_stat.st_mode) ? 'd' : '-';
mode_str[1] = (file_stat.st_mode & S_IRUSR) ? 'r' : '-';
mode_str[2] = (file_stat.st_mode & S_IWUSR) ? 'w' : '-';
mode_str[3] = (file_stat.st_mode & S_IXUSR) ? 'x' : '-';
mode_str[4] = (file_stat.st_mode & S_IRGRP) ? 'r' : '-';
mode_str[5] = (file_stat.st_mode & S_IWGRP) ? 'w' : '-';
mode_str[6] = (file_stat.st_mode & S_IXGRP) ? 'x' : '-';
mode_str[7] = (file_stat.st_mode & S_IROTH) ? 'r' : '-';
mode_str[8] = (file_stat.st_mode & S_IWOTH) ? 'w' : '-';
mode_str[9] = (file_stat.st_mode & S_IXOTH) ? 'x' : '-';
mode_str[10] = 0;
if (mode_str[0] == '-' && (mode_str[3] == 'x' || mode_str[6] == 'x' || mode_str[9] == 'x')) { if (mode_str[0] == '-' && (mode_str[3] == 'x' || mode_str[6] == 'x' || mode_str[9] == 'x')) {
color = EXE_COLOR; color = EXE_COLOR;
} }
/* mode_str(11) + time(17) + size_size + 2 spaces + 1 null */ /* mode_str + time(17) + size_size + 2 spaces + 1 null */
size_t stat_size = 11 + time_size + size_size + 3; size_t stat_size = 11 + 17 + size_size + 3;
char *total_stat = memalloc(stat_size); char *total_stat = memalloc(stat_size);
snprintf(total_stat, stat_size, "%s %s %-*s", mode_str, time, size_size, size); sprintf(total_stat, "%s %s %-*s", mode_str, time, size_size, size);
/* DIR if color is blue */ /* DIR if color is blue */
if (color == 34) if (color == 34)
arraylist_add(tmp1, filename, path, total_stat, type, icon_str, color, 0, 0); arraylist_add(tmp1, filename, path, total_stat, type, icon_str, color, 0, 0);
else else
arraylist_add(tmp2, filename, path, total_stat, type, icon_str, color, 0, 0); arraylist_add(tmp2, filename, path, total_stat, type, icon_str, color, 0, 0);
free(time);
free(size);
free(mode_str);
}
/*
* get file mode string from stat mode
* eg: drwxr-sr-x
*/
char *get_file_mode(mode_t mode)
{
char *mode_str = memalloc(11);
mode_str[0] = S_ISDIR(mode) ? 'd' : '-';
mode_str[1] = (mode & S_IRUSR) ? 'r' : '-';
mode_str[2] = (mode & S_IWUSR) ? 'w' : '-';
mode_str[3] = (mode & S_IXUSR) ? 'x' : '-';
mode_str[4] = (mode & S_IRGRP) ? 'r' : '-';
mode_str[5] = (mode & S_IWGRP) ? 'w' : '-';
mode_str[6] = (mode & S_IXGRP) ? 'x' : '-';
mode_str[7] = (mode & S_IROTH) ? 'r' : '-';
mode_str[8] = (mode & S_IWOTH) ? 'w' : '-';
mode_str[9] = (mode & S_IXOTH) ? 'x' : '-';
mode_str[10] = '\0';
return mode_str;
} }
/* /*
@ -796,11 +796,11 @@ void list_files(void)
if (num_marked > 0) { if (num_marked > 0) {
/* Determine length of formatted string */ /* Determine length of formatted string */
int m_len = snprintf(NULL, 0, "[%ld] selected", num_marked); int m_len = snprintf(NULL, 0, "[%ld] selected", num_marked);
char *selected = memalloc(m_len + 1); char selected[m_len + 1];
snprintf(selected, m_len + 1, "[%ld] selected", num_marked); snprintf(selected, m_len + 1, "[%ld] selected", num_marked);
wpprintw("(%ld/%ld) %s %s", sel_file + 1, files->length, selected, cwd); wpprintw("(%ld/%ld) %s %s", sel_file + 1, files->length, selected, cwd);
} else { } else {
wpprintw("(%ld/%ld) %s", sel_file + 1, files->length, cwd); wpprintw("(%ld/%ld) %s", sel_file + 1, files->length, cwd);
} }
} }
@ -810,8 +810,8 @@ void list_files(void)
/* check is file marked for action */ /* check is file marked for action */
int is_marked = arraylist_search(marked, files->items[i].path, 0) != -1; int is_marked = arraylist_search(marked, files->items[i].path, 0) != -1;
move_cursor(i + 1, 1); move_cursor(i + 1, 1);
if (is_marked) color = 32; if (is_marked) color = MAR_COLOR;
bprintf("\033[30m\033[%dm%s\033[0m\n", bprintf("\033[30m\033[%dm%s\033[m\n",
is_selected ? color + 10 : color, line); is_selected ? color + 10 : color, line);
free(line); free(line);
@ -885,7 +885,7 @@ void show_file_content(void)
return; return;
} }
FILE *file = fopen(current_file.path, "r"); FILE *file = fopen(current_file.path, "r");
if (file == NULL) { if (!file) {
bprintf("Unable to read %s", current_file.name); bprintf("Unable to read %s", current_file.name);
return; return;
} }
@ -919,7 +919,7 @@ void show_file_content(void)
char buffer[4096]; char buffer[4096];
int row = 1; int row = 1;
FILE *stream = fdopen(pipe_fd[0], "r"); FILE *stream = fdopen(pipe_fd[0], "r");
while (fgets(buffer, sizeof(buffer), stream) != NULL && row <= rows - 1) { while (fgets(buffer, sizeof(buffer), stream) && row <= rows - 1) {
buffer[strcspn(buffer, "\n")] = 0; buffer[strcspn(buffer, "\n")] = 0;
if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) { if (buffer[0] == '\0' || strspn(buffer, " \t") == strlen(buffer)) {
@ -982,9 +982,9 @@ void show_file_content(void)
*/ */
void edit_file(void) void edit_file(void)
{ {
if (editor == NULL) { if (!strcmp(editor, "")) {
editor = getenv("EDITOR"); editor = getenv("EDITOR");
if (editor == NULL) { if (!editor) {
wpprintw("$EDITOR not defined"); wpprintw("$EDITOR not defined");
return; return;
} }
@ -1011,21 +1011,23 @@ void toggle_executable(void)
file f = files->items[sel_file]; file f = files->items[sel_file];
struct stat st; struct stat st;
if (stat(f.path, &st) == -1) { if (stat(f.path, &st) == -1) {
wpprintw("stat failed: %s", strerror(errno)); wpprintw("stat failed: %s (Press any key to continue)", strerror(errno));
readch();
return;
} }
if (f.type == DRY) if (f.type == DRY)
return; return;
/* chmod by xor executable bits */ /* chmod by xor executable bits */
if (chmod(f.path, st.st_mode ^ (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) { if (chmod(f.path, st.st_mode ^ (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) {
wpprintw("Error toggling executable: %s", strerror(errno)); wpprintw("Error toggling executable: %s (Press any key to continue)", strerror(errno));
readch();
} }
} }
void replace_home(char *str) void replace_home(char *str)
{ {
char *home = getenv("HOME"); char *home = getenv("HOME");
if (home == NULL) { if (!home) {
wpprintw("$HOME not defined"); wpprintw("$HOME not defined");
return; return;
} }
@ -1052,12 +1054,12 @@ int write_last_d(void)
strcpy(last_ddup, last_d); strcpy(last_ddup, last_d);
char *last_d_dir = strrchr(last_ddup, '/'); char *last_d_dir = strrchr(last_ddup, '/');
if (last_d_dir != NULL) { if (last_d_dir) {
*last_d_dir = '\0'; /* truncate string */ *last_d_dir = '\0'; /* truncate string */
} }
mkdir_p(last_ddup); mkdir_p(last_ddup);
FILE *last_d_file = fopen(last_d, "w"); FILE *last_d_file = fopen(last_d, "w");
if (last_d_file == NULL) { if (!last_d_file) {
wpprintw("Cannot open last directory file (Press any key to continue)"); wpprintw("Cannot open last directory file (Press any key to continue)");
return -1; return -1;
} }
@ -1126,7 +1128,8 @@ void rename_file(void)
if (!input) { if (!input) {
return; return;
} }
char *newfilename = estrdup(filename); char newfilename[PATH_MAX];
strcpy(newfilename, filename);
/* remove basename of newfilename */ /* remove basename of newfilename */
char *last_slash = strrchr(newfilename, '/'); char *last_slash = strrchr(newfilename, '/');
*last_slash = '\0'; *last_slash = '\0';
@ -1141,12 +1144,14 @@ void rename_file(void)
wpprintw("Renamed %s to %s", filename, newfilename); wpprintw("Renamed %s to %s", filename, newfilename);
} }
free(input); free(input);
free(newfilename);
} }
void goto_dir(void) void goto_dir(void)
{ {
char *input = get_panel_string("Goto dir: "); char *input = get_panel_string("Goto dir: ");
if (!input) {
return;
}
struct stat st; struct stat st;
if (lstat(input, &st)) { if (lstat(input, &st)) {
wpprintw("lstat failed: %s (Press any key to continue)", strerror(errno)); wpprintw("lstat failed: %s (Press any key to continue)", strerror(errno));
@ -1157,16 +1162,21 @@ void goto_dir(void)
wpprintw("chdir failed: %s (Press any key to continue)", strerror(errno)); wpprintw("chdir failed: %s (Press any key to continue)", strerror(errno));
readch(); readch();
} }
getcwd(cwd, PATH_MAX); char new_cwd[PATH_MAX];
change_dir(cwd, 0, 0); getcwd(new_cwd, PATH_MAX);
change_dir(new_cwd, 0, 0);
free(input); free(input);
} }
void create_dir(void) void create_dir(void)
{ {
char *input = get_panel_string("New dir: "); char *input = get_panel_string("New dir: ");
char *newfilename = memalloc(PATH_MAX); if (!input) {
return;
}
char newfilename[PATH_MAX];
snprintf(newfilename, PATH_MAX, "%s/%s", cwd, input); snprintf(newfilename, PATH_MAX, "%s/%s", cwd, input);
if (access(newfilename, F_OK) != 0) { if (access(newfilename, F_OK) != 0) {
mkdir_p(newfilename); mkdir_p(newfilename);
change_dir(cwd, 0, 0); change_dir(cwd, 0, 0);
@ -1175,12 +1185,14 @@ void create_dir(void)
wpprintw("Directory already exist"); wpprintw("Directory already exist");
} }
free(input); free(input);
free(newfilename);
} }
void create_file(void) void create_file(void)
{ {
char *input = get_panel_string("New file: "); char *input = get_panel_string("New file: ");
if (!input) {
return;
}
FILE *f = fopen(input, "w+"); FILE *f = fopen(input, "w+");
fclose(f); fclose(f);
change_dir(cwd, 0, 0); change_dir(cwd, 0, 0);
@ -1192,16 +1204,15 @@ void delete_files(void)
{ {
if (marked->length) { if (marked->length) {
char *trash_dir = check_trash_dir(); char *trash_dir = check_trash_dir();
if (trash_dir != NULL) { if (trash_dir) {
for (int i = 0; i < marked->length; i++) { for (int i = 0; i < marked->length; i++) {
char *new_path = memalloc(PATH_MAX); char new_path[PATH_MAX];
snprintf(new_path, PATH_MAX, "%s/%s", trash_dir, marked->items[i].name); snprintf(new_path, PATH_MAX, "%s/%s", trash_dir, marked->items[i].name);
if (rename(marked->items[i].path, new_path)) { if (rename(marked->items[i].path, new_path)) {
wpprintw("delete failed: %s", strerror(errno)); wpprintw("delete failed: %s", strerror(errno));
} else {
change_dir(cwd, 0, 0);
} }
} }
change_dir(cwd, 0, 0);
for (int i = 0; i < marked->length; i++) { for (int i = 0; i < marked->length; i++) {
arraylist_remove(marked, 0); arraylist_remove(marked, 0);
} }
@ -1253,6 +1264,44 @@ void yank_clipboard(void)
} }
} }
void view_file_attr(void)
{
bprintf("\033[2J");
move_cursor(1, 1);
pid_t pid = fork();
if (pid == 0) {
/* Child process */
execlp("stat", "stat", files->items[sel_file].name, NULL);
_exit(1); /* Exit if exec fails */
} else if (pid > 0) {
/* Parent process */
waitpid(pid, NULL, 0);
} else {
/* Fork failed */
wpprintw("fork failed: %s", strerror(errno));
}
readch();
}
void show_history(void)
{
bprintf("\033[2J");
move_cursor(1, 1);
char history_path[PATH_MAX];
strcpy(history_path, "~/.cache/ccc/history");
replace_home(history_path);
FILE *history_file = fopen(history_path, "r");
char buffer[PATH_MAX];
int row = 1;
while (fgets(buffer, sizeof(buffer), history_file) && row <= rows - 1) {
move_cursor(row++, 1);
bprintf(buffer);
}
fclose(history_file);
readch();
}
/* /*
* Print line to the panel * Print line to the panel
*/ */

View file

@ -13,6 +13,7 @@ enum files_colors {
FIF_COLOR = 35, /* FIFO */ FIF_COLOR = 35, /* FIFO */
DEF_COLOR = 37, /* Default */ DEF_COLOR = 37, /* Default */
EXE_COLOR = 32, /* Executable file */ EXE_COLOR = 32, /* Executable file */
MAR_COLOR = 36, /* Marked files */
}; };
/* Set width offset for windows: /* Set width offset for windows:

29
file.c
View file

@ -23,8 +23,6 @@ void arraylist_free(ArrayList *list)
free(list->items[i].path); free(list->items[i].path);
if (list->items[i].stats != NULL) if (list->items[i].stats != NULL)
free(list->items[i].stats); free(list->items[i].stats);
if (list->items[i].icon != NULL)
free(list->items[i].icon);
} }
free(list->items); free(list->items);
@ -72,7 +70,8 @@ void arraylist_remove(ArrayList *list, long index)
*/ */
void arraylist_add(ArrayList *list, char *name, char *path, char *stats, int type, char *icon, int color, int marked, int force) void arraylist_add(ArrayList *list, char *name, char *path, char *stats, int type, char *icon, int color, int marked, int force)
{ {
file new_file = { name, path, type, stats, icon, color }; file new_file = { name, path, type, stats, color };
strcpy(new_file.icon, icon);
if (list->capacity != list->length) { if (list->capacity != list->length) {
if (marked) { if (marked) {
@ -106,29 +105,27 @@ void arraylist_add(ArrayList *list, char *name, char *path, char *stats, int typ
*/ */
char *get_line(ArrayList *list, long index, int detail, int icons) char *get_line(ArrayList *list, long index, int detail, int icons)
{ {
file file = list->items[index]; file f = list->items[index];
size_t name_len = strlen(file.name); size_t length = strlen(f.name) + 1;
size_t length;
if (detail) { if (detail) {
length = name_len + strlen(file.stats) + 7; /* 4 for icon, 2 for space and 1 for null */ length += strlen(f.stats) + 1; /* 1 for space */
} else { }
length = name_len + 6; /* 4 for icon, 1 for space and 1 for null */ if (icons) {
length += 5; /* 4 for icon, 1 for space */
} }
char *line = memalloc(length); char *line = memalloc(length);
line[0] = '\0'; line[0] = '\0';
if (detail) { if (detail) {
strcat(line, file.stats); strcat(line, f.stats);
strcat(line, " "); strcat(line, " ");
} }
if (icons) { if (icons) {
char *tmp = memalloc(10); strcat(line, f.icon);
snprintf(tmp, 10, "%s ", file.icon); strcat(line, " ");
strcat(line, tmp);
free(tmp);
} }
strcat(line, file.name); strcat(line, f.name);
line[length] = '\0';
return line; return line;
} }

6
file.h
View file

@ -13,16 +13,16 @@ enum ftypes {
FIF FIF
}; };
typedef struct file { typedef struct {
char *name; /* basename */ char *name; /* basename */
char *path; /* absolute path */ char *path; /* absolute path */
int type; int type;
char *stats; char *stats;
char *icon;
int color; int color;
char icon[5];
} file; } file;
typedef struct ArrayList { typedef struct {
size_t length; size_t length;
size_t capacity; size_t capacity;
file *items; file *items;