From 8e00d74259f98d707e9ba04d982c34d4da66a584 Mon Sep 17 00:00:00 2001
From: Arun Prakash Jana <engineerarun@gmail.com>
Date: Sat, 27 Jul 2019 12:14:49 +0530
Subject: [PATCH] Support archiving with default utils

---
 src/nnn.c | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/src/nnn.c b/src/nnn.c
index 305d54fb..4bc38390 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -135,6 +135,7 @@
 #define EXEC_ARGS_MAX 8
 #define SCROLLOFF 3
 #define LONG_SIZE sizeof(ulong)
+#define ARCHIVE_CMD_LEN 12
 
 /* Program return codes */
 #define _SUCCESS 0
@@ -474,6 +475,7 @@ static int spawn(char *file, char *arg1, char *arg2, const char *dir, uchar flag
 static int (*nftw_fn)(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
 static int dentfind(const char *fname, int n);
 static void move_cursor(int target, int ignore_scrolloff);
+static bool getutil(const char *util);
 
 /* Functions */
 
@@ -727,6 +729,20 @@ static size_t xstrlcpy(char *dest, const char *src, size_t n)
 	return len;
 }
 
+static bool is_suffix(const char *str, const char *suffix)
+{
+	if (!str || !suffix)
+		return FALSE;
+
+	size_t lenstr = strlen(str);
+	size_t lensuffix = strlen(suffix);
+
+	if (lensuffix > lenstr)
+		return FALSE;
+
+	return (xstrcmp(str + (lenstr - lensuffix), suffix) == 0);
+}
+
 /*
  * The poor man's implementation of memrchr(3).
  * We are only looking for '/' in this program.
@@ -1263,6 +1279,18 @@ finish:
 	return ret;
 }
 
+static void get_archive_cmd(char *cmd, char *archive)
+{
+	if (getutil(utils[ATOOL]))
+		xstrlcpy(cmd, "atool -a", ARCHIVE_CMD_LEN);
+	else if (getutil(utils[BSDTAR]))
+		xstrlcpy(cmd, "bsdtar -cvf", ARCHIVE_CMD_LEN);
+	else if (is_suffix(archive, ".zip"))
+		xstrlcpy(cmd, "zip -r", ARCHIVE_CMD_LEN);
+	else
+		xstrlcpy(cmd, "tar -cvf", ARCHIVE_CMD_LEN);
+}
+
 static void archive_selection(const char *cmd, const char *archive, const char *curpath)
 {
 	char *buf = (char *)malloc(CMD_LEN_MAX * sizeof(char));
@@ -4141,14 +4169,9 @@ nochange:
 			switch (sel) {
 			case SEL_ARCHIVE:
 			{
-				char cmd[] = "bsdtar -cf";
+				char cmd[ARCHIVE_CMD_LEN];
 
-				if (getutil(utils[ATOOL]))
-					xstrlcpy(cmd, "atool -a", 10);
-				else if (!getutil(utils[BSDTAR])) {
-					printwait(messages[UTIL_MISSING], &presel);
-					goto nochange;
-				}
+				get_archive_cmd(cmd, tmp);
 
 				(r == 'y' || r == 'Y') ? archive_selection(cmd, tmp, path)
 						       : spawn(cmd, tmp, dents[cur].name,
-- 
2.51.0