sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit 9e8b431075c0901a58dda7eee3f18d97095896ca
parent 8d07e5e8f639f3fabb45379786c9225f7312e6e5
Author: Thibaut Aubin <t.aubin20@ejm.org>
Date:   Thu, 10 Apr 2025 00:00:00 +0000

cp: add -i flag

Diffstat:
MREADME | 2+-
Mcp.1 | 6++++--
Mcp.c | 5++++-
Mfs.h | 1+
Mlibutil/cp.c | 8++++++++
5 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/README b/README @@ -56,7 +56,7 @@ The following tools are implemented: 0=*|o cmp . 0#*|x cols . 0=*|o comm . -0=*|o cp (-i) +0=*|o cp . 0=*|x cron . 0#*|o cut . 0=*|o date . diff --git a/cp.1 b/cp.1 @@ -1,4 +1,4 @@ -.Dd October 8, 2015 +.Dd April 10, 2025 .Dt CP 1 .Os sbase .Sh NAME @@ -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 @@ -37,6 +37,8 @@ and If an existing .Ar dest cannot be opened, remove it and try again. +.It Fl i +Interactive prompt before overwrite. .It Fl p Preserve mode, timestamp and permissions. .It Fl v diff --git a/cp.c b/cp.c @@ -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 @@ -16,6 +16,9 @@ main(int argc, char *argv[]) struct stat st; ARGBEGIN { + case 'i': + cp_iflag = 1; + break; case 'a': cp_follow = 'P'; cp_aflag = cp_pflag = cp_rflag = 1; diff --git a/fs.h b/fs.h @@ -28,6 +28,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 @@ -16,6 +16,7 @@ int cp_aflag = 0; int cp_fflag = 0; +int cp_iflag = 0; int cp_pflag = 0; int cp_rflag = 0; int cp_vflag = 0; @@ -42,6 +43,13 @@ cp(const char *s1, const char *s2, int depth) return 0; } + if (cp_iflag && access(s2, F_OK) == 0) { + if (!confirm("overwrite '%s'? ", s2)) { + cp_status = 1; + return 0; + } + } + if (cp_vflag) printf("%s -> %s\n", s1, s2);