logo

utils-std

Collection of commonly available Unix tools
commit: 22dfbb18eb5f9d669a809044b9ec42e8f29805ed
parent d097ffcc3d4523805037c21ed67813deb1591ccd
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 10 Jul 2024 01:50:48 +0200

cmd/install: Add support for -t option

Diffstat:

Mcmd/install.113+++++++++++++
Mcmd/install.c22++++++++++++++--------
Mtest-cmd/install.t17++++++++++++++++-
3 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/cmd/install.1 b/cmd/install.1 @@ -16,6 +16,13 @@ .Ar source... .Ar destination .Nm +.Op Fl cDpT +.Op Fl g Ar group +.Op Fl m Ar mode +.Op Fl o Ar owner +.Fl t Ar destination +.Ar source... +.Nm .Fl d .Op Fl c .Op Fl g Ar group @@ -66,6 +73,12 @@ The default mode is set to Sets user ownership. .It Fl p Preserve file access and modification times. +.It Fl t Ar destination +Use +.Ar destination +as directory to copy each +.Ar source +into. .It Fl T Treat .Ar destination diff --git a/cmd/install.c b/cmd/install.c @@ -188,6 +188,7 @@ usage() { fprintf(stderr, "\ Usage: install [-cDpT] [-g group] [-m mode] [-o owner] source... destination\n\ + install [-cDpT] [-g group] [-m mode] [-o owner] -t destination source...\n\ install -d [-c] [-g group] [-m mode] [-o owner] directory...\n\ "); } @@ -198,12 +199,13 @@ main(int argc, char *argv[]) const char *errstr = NULL; bool create_parents = false; bool opt_T = false; + char *dest = NULL; mkdir_parents_filemask = umask(0); umask(mkdir_parents_filemask); int c = -1; - while((c = getopt(argc, argv, ":cDdpTg:m:o:")) != -1) + while((c = getopt(argc, argv, ":cDdpTt:g:m:o:")) != -1) { switch(c) { @@ -228,6 +230,9 @@ main(int argc, char *argv[]) case 'T': opt_T = true; break; + case 't': + dest = optarg; + break; case 'm': mode = new_mode(optarg, 0755, &errstr); if(errstr != NULL) @@ -277,22 +282,23 @@ main(int argc, char *argv[]) return 0; } - char *dest = argv[argc - 1]; - bool multi_src = argc > 2; + if(dest == NULL) dest = argv[--argc]; + bool multi_src = argc > 1; if(opt_T) { - if(argc != 2) + if(argc != 1) { - fprintf(stderr, "%s: Option -T passed, expected exactly 2 operands, got %d\n", argv0, argc); + fprintf( + stderr, "%s: Option -T passed, expected exactly 1 source operand, got %d\n", argv0, argc); return 1; } assert(!multi_src); } - else if(argc < 2) + else if(argc < 1) { - fprintf(stderr, "%s: Expected at least 2 operands, got %d\n", argv0, argc); + fprintf(stderr, "%s: Expected at least 1 source operand\n", argv0); return 1; } @@ -313,7 +319,7 @@ main(int argc, char *argv[]) if(mkdir_parents(destdir, parent_mode) != 0) return 1; } - for(int i = 0; i < argc - 1; i++) + for(int i = 0; i < argc; i++) { char *src = argv[i]; if(do_install(src, dest, multi_src) < 0) return 1; diff --git a/test-cmd/install.t b/test-cmd/install.t @@ -78,13 +78,28 @@ install -T $ test -e dest_T $ rm dest_T $ install -T src_T src2_T bogus_T - install: Option -T passed, expected exactly 2 operands, got 3 + install: Option -T passed, expected exactly 1 source operand, got 2 [1] $ test -e src_T $ test ! -e src2_T $ test ! -e bogus_T $ rm src_T +install -t + $ touch src1_t src2_t + $ test -e src1_t + $ test -e src2_t + $ mkdir dest_t + $ test -d dest_t + $ test ! -e dest_t/src1_t + $ test ! -e dest_t/src2_t + $ install -t dest_t src1_t src2_t + $ test -e src1_t + $ test -e src2_t + $ test -e dest_t/src1_t + $ test -e dest_t/src2_t + $ rm -r dest_t src1_t src2_t + No files should be left $ find . .