diff --git a/README.md b/README.md index 6b2d021..eb95649 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ minimal. - `fzf` for searching - `w3mimgdisplay` or `Überzug` for image previews - `mediainfo` for viewing media info and file sizes -- `sed` for removing a particular selection - `atool` for archive previews ## Compiling and Installation @@ -49,6 +48,7 @@ Arch Linux users can use the [AUR](https://aur.archlinux.org/packages/cfiles) pa | dd | Move files from selection list to trash | | dD | Remove selected files | | i | View mediainfo and general info | +| I | View preview | | . | Toggle hidden files | | ' | View/Goto bookmarks | | m | Add bookmark | @@ -72,8 +72,7 @@ or press `m` in `cfiles` to add new bookmarks. If `$XDG_CACHE_HOME` is not set, then `$HOME/.cache` is used. ## Opening Files -You can set `FILE_OPENER` in `config.h` to specify your file opening program. It is set to use `xdg-open` by default but you can change it to anything like `thunar`. macOS users need to set it to `/usr/bin/open`. -Note that you have to specify the full path of the binary. +You can set `FILE_OPENER` in `config.h` to specify your file opening program. It is set to use `xdg-open` by default but you can change it to anything like `thunar`. macOS users need to set it to `open`. ## Image Previews You can either go with `w3mimgdisplay` or `Überzug` ([link](https://github.com/seebye/ueberzug)) for image previews. diff --git a/cf.c b/cf.c index 9a61b28..a7bb839 100644 --- a/cf.c +++ b/cf.c @@ -465,53 +465,65 @@ int compare (const void * a, const void * b ) void getMIME(char *filepath, char mime[50]) { char buf[50]; - char *cmd = NULL; FILE *fp; + int fd; + pid_t pid; + + // Reallocate `temp_dir` and store path to preview file + free(temp_dir); + allocSize = snprintf(NULL,0,"%s/mime",cache_path); + temp_dir = malloc(allocSize+1); + snprintf(temp_dir,allocSize+1,"%s/mime",cache_path); - // Allocate Memory to `cmd` - allocSize = snprintf(NULL, 0, "xdg-mime query filetype \'%s\'", filepath); - cmd = malloc(allocSize+1); - snprintf(cmd, allocSize+1, "xdg-mime query filetype \'%s\'", filepath); + // Remove the preview file + remove(temp_dir); - if((fp = popen(cmd,"r")) == NULL) + // Create a child process to run command and store output in preview file + pid = fork(); + if( pid == 0 ) { - exit(0); + fd = open(temp_dir, O_CREAT | O_WRONLY, 0755); + dup2(fd, 1); + execlp("xdg-mime","xdg-mime","query","filetype",filepath,(char *)0); + exit(1); } + else + { + int status; + waitpid(pid,&status,0); + } + + // Open preview file to read output + fp = fopen(temp_dir, "r"); while(fgets(buf,50,fp) != NULL){} + fclose(fp); strtok(buf,"/"); snprintf(mime,50,"%s",buf); - free(cmd); } /* Opens a file using FILE_OPENER - */ +*/ void openFile(char *filepath) { char mime[50]; getMIME(filepath, mime); if(strcmp(mime,"text") == 0) { - char *cmd; - // Allocate Memory to `cmd` - allocSize = snprintf(NULL, 0, "%s/%s", "/usr/bin", editor); - cmd = malloc(allocSize+1); - snprintf(cmd, allocSize+1, "%s/%s", "/usr/bin", editor); endwin(); // Make a child process to edit file pid_t pid; pid = fork(); if (pid == 0) { - execl(cmd, cmd, filepath, (char *)0); + execlp(editor, editor, filepath, (char *)0); exit(1); } else { int status; waitpid(pid, &status, 0); - free(cmd); return; } } @@ -519,7 +531,7 @@ void openFile(char *filepath) pid = fork(); if (pid == 0) { - execl(FILE_OPENER, FILE_OPENER, filepath, (char *)0); + execlp(FILE_OPENER, FILE_OPENER, filepath, (char *)0); exit(1); } } @@ -580,33 +592,34 @@ void writeClipboard(char *filepath) */ void removeClipboard(char *filepath) { - char *cmd = NULL; - char *arg = NULL; - - // Allocate Memory to `cmd` - allocSize = snprintf(NULL, 0, "%s", "/usr/bin/sed"); - cmd = malloc(allocSize+1); - snprintf(cmd, allocSize+1, "%s", "/usr/bin/sed"); + FILE *f1; + FILE *f2; + char buf[PATH_MAX]; - // Allocate Memory to `arg` - allocSize = snprintf(NULL, 0, "\\|^%s|d", filepath); - arg = malloc(allocSize + 1); - snprintf(arg, allocSize+1, "\\|^%s|d", filepath); + // Create `temp_clipboard` without `filepath` + f1 = fopen(clipboard_path,"r"); + f2 = fopen(temp_clipboard_path,"a+"); + while(fgets(buf, PATH_MAX, (FILE*)f1)) + { + buf[strlen(buf)-1] = '\0'; + if(strcasecmp(buf, filepath) != 0) + fprintf(f2, "%s\n", buf); + } + fclose(f1); + fclose(f2); - // Create a child process to run command + // Create a child process to replace clipboard_path with temp_clipboard_path pid_t pid; pid = fork(); if( pid == 0 ) { - execl(cmd, cmd, "-i", arg, clipboard_path, (char *)0); + execlp("mv", "mv", temp_clipboard_path, clipboard_path, (char *)0); exit(1); } else { int status; waitpid(pid, &status, 0); - free(arg); - free(cmd); } } @@ -660,68 +673,76 @@ void getTextPreview(char *filepath, int maxy, int maxx) stat(filepath, &st); if(st.st_size > 10000000) return; - FILE *fp = fopen(filepath,"r"); - if(fp == NULL) - return; - char buf[250]; - int t=0; - while(fgets(buf, 250, (FILE*) fp)) - { - wmove(preview_win,t+1,2); - wprintw(preview_win,"%.*s",maxx-4,buf); - t++; - } - wrefresh(preview_win); - - fclose(fp); -} - -/* - Gets previews of video files -*/ -void getVidPreview(char *filepath, int maxy, int maxx) -{ - pid_t pid; - int fd; - - // Reallocate `temp_dir` and store path to preview file - free(temp_dir); - allocSize = snprintf(NULL,0,"%s/preview",cache_path); - temp_dir = malloc(allocSize+1); - snprintf(temp_dir,allocSize+1,"%s/preview",cache_path); + // Buffer for file reading + char buf[250]; - endwin(); + // Set path to preview file + char *preview_path = NULL; + allocSize = snprintf(NULL, 0, "%s/preview", cache_path); + preview_path = malloc(allocSize+1); + snprintf(preview_path, allocSize+1, "%s/preview", cache_path); - // Create a child process to run "mediainfo filepath > ~/.cache/cfiles/preview" - pid = fork(); - if( pid == 0 ) - { - remove(temp_dir); - fd = open(temp_dir, O_CREAT | O_WRONLY, 0755); - // Redirect stdout - dup2(fd, 1); - execl("/usr/bin/mediainfo", "mediainfo", filepath, (char *)0); - exit(1); - } - else + // Generate Hex Preview if file is a binary + char mime[50]; + getMIME(filepath, mime); + if(strcasecmp(mime,"application") == 0) { - int status; - waitpid(pid, &status, 0); - - pid = fork(); - if( pid == 0 ) + remove(preview_path); + pid_t pid = fork(); + if(pid == 0) { - execl("/usr/bin/less", "less", temp_dir, (char *)0); + int fd = open(preview_path, O_CREAT | O_WRONLY, 0755); + dup2(fd,1); + execlp("hexdump","hexdump",filepath,(char*)0); exit(1); } else { + int status; waitpid(pid, &status, 0); + FILE *fp = fopen(preview_path, "r"); + int t=0; + while(fgets(buf, 250, (FILE*) fp)) + { + wmove(preview_win,t+1,2); + wprintw(preview_win,"%.*s",maxx-4,buf); + t++; + } + wrefresh(preview_win); + fclose(fp); } + free(preview_path); + return; + } - refresh(); + // Copy file to `preview_path` + pid_t pid = fork(); + if(pid == 0) + { + int fd = open("/dev/null", O_WRONLY); + dup2(fd,2); + execlp("cp","cp",filepath,preview_path,(char*)0); + exit(1); + } + + // Print the preview + FILE *fp = fopen(filepath,"r"); + if(fp == NULL) + { + free(preview_path); + return; + } + int t=0; + while(fgets(buf, 250, (FILE*) fp)) + { + wmove(preview_win,t+1,2); + wprintw(preview_win,"%.*s",maxx-4,buf); + t++; } + wrefresh(preview_win); + free(preview_path); + fclose(fp); } @@ -735,30 +756,31 @@ void getArchivePreview(char *filepath, int maxy, int maxx) int null_fd; // Reallocate `temp_dir` and store path to preview file - free(temp_dir); - allocSize = snprintf(NULL,0,"%s/preview",cache_path); - temp_dir = malloc(allocSize+1); - snprintf(temp_dir,allocSize+1,"%s/preview",cache_path); + char *preview_path = NULL; + allocSize = snprintf(NULL, 0, "%s/preview", cache_path); + preview_path = malloc(allocSize+1); + snprintf(preview_path, allocSize+1, "%s/preview", cache_path); // Create a child process to run "atool -lq filepath > ~/.cache/cfiles/preview" pid = fork(); if( pid == 0 ) { - remove(temp_dir); - fd = open(temp_dir, O_CREAT | O_WRONLY, 0755); + remove(preview_path); + fd = open(preview_path, O_CREAT | O_WRONLY, 0755); null_fd = open("/dev/null", O_WRONLY); // Redirect stdout dup2(fd, 1); // Redirect errors to /dev/null dup2(null_fd, 2); - execl("/usr/bin/atool", "atool", "-lq", filepath, (char *)0); + execlp("atool", "atool", "-lq", filepath, (char *)0); exit(1); } else { int status; waitpid(pid, &status, 0); - getTextPreview(temp_dir, maxy, maxx); + getTextPreview(preview_path, maxy, maxx); + free(preview_path); } } @@ -807,6 +829,53 @@ void getPreview(char *filepath, int maxy, int maxx) } +/* + Gets previews of video files +*/ +void getVidPreview(char *filepath, int maxy, int maxx) +{ + pid_t pid; + int fd; + + // Reallocate `temp_dir` and store path to preview file + free(temp_dir); + allocSize = snprintf(NULL,0,"%s/preview",cache_path); + temp_dir = malloc(allocSize+1); + snprintf(temp_dir,allocSize+1,"%s/preview",cache_path); + + endwin(); + + // Create a child process to run "mediainfo filepath > ~/.cache/cfiles/preview" + pid = fork(); + if( pid == 0 ) + { + remove(temp_dir); + fd = open(temp_dir, O_CREAT | O_WRONLY, 0755); + // Redirect stdout + dup2(fd, 1); + execlp("mediainfo", "mediainfo", filepath, (char *)0); + exit(1); + } + else + { + int status; + waitpid(pid, &status, 0); + pid = fork(); + if( pid == 0 ) + { + execlp("less", "less", temp_dir, (char *)0); + exit(1); + } + else + { + waitpid(pid, &status, 0); + } + + refresh(); + } +} + + /* Gets path of parent directory */ @@ -902,7 +971,7 @@ void copyFiles(char *present_dir) pid_t pid = fork(); if(pid == 0) { - execl("/usr/bin/cp", "cp", "-r", "-v", buf, present_dir, (char *)0); + execlp("cp", "cp", "-r", "-v", buf, present_dir, (char *)0); exit(1); } else @@ -934,7 +1003,7 @@ void removeFiles() pid_t pid = fork(); if(pid == 0) { - execl("/usr/bin/rm", "rm", "-r", "-v", buf, (char *)0); + execlp("rm", "rm", "-r", "-v", buf, (char *)0); exit(1); } else @@ -976,7 +1045,7 @@ void renameFiles() pid = fork(); if( pid == 0 ) { - execl("/usr/bin/cp", "cp", clipboard_path, temp_clipboard_path, (char *)0); + execlp("cp", "cp", clipboard_path, temp_clipboard_path, (char *)0); exit(1); } else @@ -989,15 +1058,15 @@ void renameFiles() endwin(); // Allocate `cmd` to store full path of editor - allocSize = snprintf(NULL,0,"/usr/bin/%s", editor); + allocSize = snprintf(NULL,0,"%s", editor); cmd = malloc(allocSize + 1); - snprintf(cmd,allocSize+1,"/usr/bin/%s", editor); + snprintf(cmd,allocSize+1,"%s", editor); // Create a child process to edit temp_clipboard pid = fork(); if( pid == 0 ) { - execl(cmd, cmd, temp_clipboard_path, (char *)0); + execlp(cmd, cmd, temp_clipboard_path, (char *)0); exit(1); } else @@ -1026,7 +1095,7 @@ void renameFiles() pid = fork(); if( pid == 0 ) { - execl("/usr/bin/mv", "mv", buf, buf2, (char *)0); + execlp("mv", "mv", buf, buf2, (char *)0); exit(1); } else @@ -1070,7 +1139,7 @@ void moveFiles(char *present_dir) pid_t pid = fork(); if(pid == 0) { - execl("/usr/bin/mv", "mv", "-v", buf, present_dir, (char *)0); + execlp("mv", "mv", "-v", buf, present_dir, (char *)0); exit(1); } else @@ -1169,6 +1238,41 @@ void clearImg() } +/* + Opens `preview` file in pager +*/ +void viewPreview() +{ + pid_t pid; + char *preview_path = NULL; + + // Store path of preview file in `preview_path` + allocSize = snprintf(NULL, 0, "%s/preview", cache_path); + preview_path = malloc(allocSize + 1); + snprintf(preview_path, allocSize+1, "%s/preview", cache_path); + + // Exit curses mode + endwin(); + + // Start a child process to display preview + pid = fork(); + if(pid == 0) + { + execlp("less", "less", preview_path, (char *)0); + exit(1); + } + else + { + int status; + waitpid(pid, &status, 0); + } + + // Restart curses mode + refresh(); + free(preview_path); +} + + /* Checks if some flags are enabled and handles them accordingly */ @@ -1246,6 +1350,7 @@ int main(int argc, char* argv[]) // Main Loop do { + signal(SIGCHLD, SIG_IGN); // Stores length of VLA `directories` int temp_len; @@ -1301,6 +1406,7 @@ int main(int argc, char* argv[]) int t = 0; for( i=start; i