[PATCH] cp: add -i flag

From: Thomas Mannay <audiobarrier_AT_openmailbox.org>
Date: Sun, 9 Oct 2016 13:05:53 +0000

---
 cp.1         | 22 ++++++++++++++++------
 cp.c         |  7 ++++++-
 fs.h         |  1 +
 libutil/cp.c | 23 +++++++++++++++++++++++
 4 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/cp.1 b/cp.1
index 54126e2..4bbe4d0 100644
--- a/cp.1
+++ b/cp.1
_AT_@ -6,7 +6,7 @@
 .Nd copy files and directories
 .Sh SYNOPSIS
 .Nm
-.Op Fl afpv
+.Op Fl afipv
 .Oo
 .Fl R
 .Op Fl H | L | P
_AT_@ -35,7 +35,15 @@ and
 .It Fl f
 If an existing
 .Ar dest
-cannot be opened, remove it and try again.
+cannot be opened, remove it and try again. Ignores
+.Fl i
+if this option is used after it
+.It Fl i
+If
+.Ar dest
+exists and is not a directory, prompt before overwriting it. Ignores
+.Fl f
+if this option is used after it.
 .It Fl p
 Preserve mode, timestamp and permissions.
 .It Fl v
_AT_@ -62,10 +70,12 @@ The
 .Nm
 utility is compliant with the
 .St -p1003.1-2013
-specification except from the
-.Op Fl i
-flag.
+specification.
 .Pp
 The
 .Op Fl av
-flags are an extension to that specification.
+flags are an extension to that specification, as is the mutual exclusivity of the
+.Fl f
+and
+.Fl i
+flags.
diff --git a/cp.c b/cp.c
index d87e77e..f72de04 100644
--- a/cp.c
+++ b/cp.c
_AT_@ -7,7 +7,7 @@
 static void
 usage(void)
 {
-	eprintf("usage: %s [-afpv] [-R [-H | -L | -P]] source ... dest\n", argv0);
+	eprintf("usage: %s [-afipv] [-R [-H | -L | -P]] source ... dest\n", argv0);
 }
 
 int
_AT_@ -22,6 +22,11 @@ main(int argc, char *argv[])
 		break;
 	case 'f':
 		cp_fflag = 1;
+		cp_iflag = 0;
+		break;
+	case 'i':
+		cp_iflag = 1;
+		cp_fflag = 0;
 		break;
 	case 'p':
 		cp_pflag = 1;
diff --git a/fs.h b/fs.h
index 15ae5f4..36b9cb3 100644
--- a/fs.h
+++ b/fs.h
_AT_@ -25,6 +25,7 @@ enum {
 
 extern int cp_aflag;
 extern int cp_fflag;
+extern int cp_iflag;
 extern int cp_pflag;
 extern int cp_rflag;
 extern int cp_vflag;
diff --git a/libutil/cp.c b/libutil/cp.c
index c398962..116addb 100644
--- a/libutil/cp.c
+++ b/libutil/cp.c
_AT_@ -17,12 +17,22 @@
 
 int cp_aflag  = 0;
 int cp_fflag  = 0;
+int cp_iflag  = 0;
 int cp_pflag  = 0;
 int cp_rflag  = 0;
 int cp_vflag  = 0;
 int cp_status = 0;
 int cp_follow = 'L';
 
+inline static int
+exists(const char *s)
+{
+	struct stat st;
+
+	stat(s, &st);
+	return S_ISREG(st.st_mode);
+}
+
 int
 cp(const char *s1, const char *s2, int depth)
 {
_AT_@ -34,6 +44,7 @@ cp(const char *s1, const char *s2, int depth)
 	ssize_t r;
 	int (*statf)(const char *, struct stat *);
 	char target[PATH_MAX], ns1[PATH_MAX], ns2[PATH_MAX], *statf_name;
+	int c, y; /* used for i flag */
 
 	if (cp_follow == 'P' || (cp_follow == 'H' && depth)) {
 		statf_name = "lstat";
_AT_@ -112,6 +123,18 @@ cp(const char *s1, const char *s2, int depth)
 			return 0;
 		}
 	} else {
+		if (cp_iflag && exists(s2)) {
+			weprintf("overwrite %s with %s? ", s2, s1);
+			y = 0;
+			while ((c = getchar()) != '\n' && c != EOF) {
+				if (c == 'y' || c == 'Y'){
+					y = 1;
+					break;
+				}
+			}
+			if (!y)
+				return 0;
+		}
 		if (!(f1 = fopen(s1, "r"))) {
 			weprintf("fopen %s:", s1);
 			cp_status = 1;
-- 
2.10.0
--Multipart=_Sun__9_Oct_2016_13_22_32_+0000_LhnI.pNklf0QT2VA--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Sun Oct 09 2016 - 15:36:12 CEST