--- cp.1 | 22 ++++++++++++++++------ cp.c | 7 ++++++- libutil/cp.c | 18 ++++++++++++++++++ 3 files changed, 40 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/libutil/cp.c b/libutil/cp.c index c398962..2a0cdd1 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; /* used for i flag */ if (cp_follow == 'P' || (cp_follow == 'H' && depth)) { statf_name = "lstat"; _AT_@ -112,6 +123,13 @@ cp(const char *s1, const char *s2, int depth) return 0; } } else { + if (cp_iflag && exists(s2)) { + weprintf("overwrite %s with %s? ", s2, s1); + while ((c = getchar()) != '\n' && c != EOF) { + if (c != 'y' && c != 'Y') + return 0; + } + } if (!(f1 = fopen(s1, "r"))) { weprintf("fopen %s:", s1); cp_status = 1; -- 2.10.0Received on Sun Oct 09 2016 - 12:11:45 CEST
This archive was generated by hypermail 2.3.0 : Sun Oct 09 2016 - 12:12:14 CEST