Support bsdtar

This commit is contained in:
Arun Prakash Jana 2019-05-19 21:29:29 +05:30
parent a752235892
commit 5f6ceb2f43
No known key found for this signature in database
GPG key ID: A75979F35C080412
2 changed files with 40 additions and 22 deletions

View file

@ -92,7 +92,7 @@ It runs on Linux, macOS, Raspberry Pi, BSD, Cygwin, Linux subsystem for Windows
- Subtree search to open or edit files (using plugin) - Subtree search to open or edit files (using plugin)
- Mimes - Mimes
- Open with desktop opener or specify a custom app - Open with desktop opener or specify a custom app
- Create, list, extract archive (needs (p)atool) - Create, list, extract archive (needs (p)atool/bsdtar)
- Option to open all text files in EDITOR - Option to open all text files in EDITOR
- Information - Information
- Detailed file information - Detailed file information
@ -138,7 +138,7 @@ The following table is a complete list. Some of the utilities may be installed b
| file, coreutils (cp, mv, rm), findutils (xargs) | detect type, copy, move and remove files | | file, coreutils (cp, mv, rm), findutils (xargs) | detect type, copy, move and remove files |
| trash-cli | trash files (default: delete) | | trash-cli | trash files (default: delete) |
| mediainfo / exiftool | multimedia file details | | mediainfo / exiftool | multimedia file details |
| atool / patool ([integration](https://github.com/jarun/nnn/wiki/hacking-nnn#integrate-patool)) | create, list and extract archives | | atool / bsdtar / patool ([integration](https://github.com/jarun/nnn/wiki/hacking-nnn#integrate-patool)) | create, list and extract archives |
| vidir (from moreutils) | batch rename dir entries | | vidir (from moreutils) | batch rename dir entries |
| sshfs, fusermount(3) | mount, unmount remote over SSHFS | | sshfs, fusermount(3) | mount, unmount remote over SSHFS |
| vlock (Linux), bashlock (macOS), lock(1) (BSD) | terminal locker | | vlock (Linux), bashlock (macOS), lock(1) (BSD) | terminal locker |

View file

@ -333,7 +333,7 @@ static char g_tmpfpath[TMP_LEN_MAX] __attribute__ ((aligned));
#define EXIFTOOL 1 #define EXIFTOOL 1
#define OPENER 2 #define OPENER 2
#define ATOOL 3 #define ATOOL 3
#define APACK 4 #define BSDTAR 4
#define VIDIR 5 #define VIDIR 5
#define LOCKER 6 #define LOCKER 6
#define NLAUNCH 7 #define NLAUNCH 7
@ -351,7 +351,7 @@ static char * const utils[] = {
"xdg-open", "xdg-open",
#endif #endif
"atool", "atool",
"apack", "bsdtar",
"vidir", "vidir",
#ifdef __APPLE__ #ifdef __APPLE__
"bashlock", "bashlock",
@ -375,6 +375,7 @@ static char mv[] = "mvg -gi";
#define STR_DATE_ID 2 #define STR_DATE_ID 2
#define STR_TMPFILE 3 #define STR_TMPFILE 3
#define NONE_SELECTED 4 #define NONE_SELECTED 4
#define UTIL_MISSING 5
static const char * const messages[] = { static const char * const messages[] = {
"no traversal", "no traversal",
@ -382,6 +383,7 @@ static const char * const messages[] = {
"%F %T %z", "%F %T %z",
"/.nnnXXXXXX", "/.nnnXXXXXX",
"empty selection", "empty selection",
"utility missing",
}; };
/* Supported configuration environment variables */ /* Supported configuration environment variables */
@ -1121,7 +1123,7 @@ static void xrm(char *path)
} }
} }
static void archive_selection(const char *archive, const char *curpath) static void archive_selection(const char *cmd, const char *archive, const char *curpath)
{ {
snprintf(g_buf, CMD_LEN_MAX, snprintf(g_buf, CMD_LEN_MAX,
#ifdef __linux__ #ifdef __linux__
@ -1129,7 +1131,7 @@ static void archive_selection(const char *archive, const char *curpath)
#else #else
"cat %s | xargs -0 -o %s %s", "cat %s | xargs -0 -o %s %s",
#endif #endif
g_cppath, utils[APACK], archive); g_cppath, cmd, archive);
spawn("sh", "-c", g_buf, curpath, F_NORMAL); spawn("sh", "-c", g_buf, curpath, F_NORMAL);
} }
@ -2379,16 +2381,27 @@ static bool show_mediainfo(const char *fpath, const char *arg)
return TRUE; return TRUE;
} }
static bool handle_archive(char *fpath, char *arg, const char *dir) /* Extracts or lists archive */
static bool handle_archive(char *fpath, const char *dir, char op)
{ {
if (!getutil(utils[ATOOL])) char larg[] = "-tf";
char xarg[] = "-xf";
char *util;
if (getutil(utils[ATOOL])) {
util = utils[ATOOL];
larg[1] = op;
larg[2] = xarg[2] = '\0';
} else if (getutil(utils[BSDTAR]))
util = utils[BSDTAR];
else
return FALSE; return FALSE;
if (arg[1] == 'x') if (op == 'x') { // extract
spawn(utils[ATOOL], arg, fpath, dir, F_NORMAL); spawn(util, xarg, fpath, dir, F_NORMAL);
else { } else { // list
exitcurses(); exitcurses();
get_output(NULL, 0, utils[ATOOL], arg, fpath, TRUE); get_output(NULL, 0, util, larg, fpath, TRUE);
refresh(); refresh();
} }
@ -2895,7 +2908,7 @@ static void move_cursor(int target, int ignore_scrolloff)
cur = target; cur = target;
if (!ignore_scrolloff) { if (!ignore_scrolloff) {
scrolloff = MIN(SCROLLOFF, onscreen >> 1); scrolloff = MIN(SCROLLOFF, onscreen >> 1);
/* /*
* When ignore_scrolloff is 1, the cursor can jump into the scrolloff * When ignore_scrolloff is 1, the cursor can jump into the scrolloff
* margin area, but when ignore_scrolloff is 0, act like a boa * margin area, but when ignore_scrolloff is 0, act like a boa
* constrictor and squeeze the cursor towards the middle region of the * constrictor and squeeze the cursor towards the middle region of the
@ -3596,10 +3609,10 @@ nochange:
setdirwatch(); setdirwatch();
goto nochange; goto nochange;
case SEL_ARCHIVELS: case SEL_ARCHIVELS:
r = handle_archive(newpath, "-l", path); r = handle_archive(newpath, path, 'l');
break; break;
case SEL_EXTRACT: case SEL_EXTRACT:
r = handle_archive(newpath, "-x", path); r = handle_archive(newpath, path, 'x');
break; break;
case SEL_REDRAW: case SEL_REDRAW:
if (ndents) if (ndents)
@ -3638,7 +3651,7 @@ nochange:
} }
if (!r) { if (!r) {
printwait("utility missing", &presel); printwait(messages[UTIL_MISSING], &presel);
goto nochange; goto nochange;
} }
@ -3879,16 +3892,21 @@ nochange:
switch (sel) { switch (sel) {
case SEL_ARCHIVE: case SEL_ARCHIVE:
/* newpath is used as temporary buffer */ {
if (!getutil(utils[APACK])) { char cmd[] = "bsdtar -cf";
printwait("utility missing", &presel);
if (getutil(utils[ATOOL]))
xstrlcpy(cmd, "atool -qa", 10);
else if (!getutil(utils[BSDTAR])) {
printwait(messages[UTIL_MISSING], &presel);
goto nochange; goto nochange;
} }
(r == 'y' || r == 'Y') ? archive_selection(tmp, path) (r == 'y' || r == 'Y') ? archive_selection(cmd, tmp, path)
: spawn(utils[APACK], tmp, dents[cur].name, : spawn(cmd, tmp, dents[cur].name,
path, F_NORMAL); path, F_NORMAL | F_MULTI);
break; break;
}
case SEL_OPENWITH: case SEL_OPENWITH:
mkpath(path, dents[cur].name, newpath); mkpath(path, dents[cur].name, newpath);
spawn(tmp, newpath, NULL, path, r); spawn(tmp, newpath, NULL, path, r);