author | Olivier Brunel
<jjk@jjacky.com> 2018-01-15 18:02:39 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2018-01-15 18:27:32 UTC |
parent | 2578593490af6ed26a342656c728e6960e27fcf3 |
doc/aa-hiercopy.pod | +59 | -0 |
package/modes | +1 | -0 |
package/targets.mak | +2 | -0 |
src/utils/aa-hiercopy.c | +105 | -0 |
src/utils/deps-exe/aa-hiercopy | +2 | -0 |
diff --git a/doc/aa-hiercopy.pod b/doc/aa-hiercopy.pod new file mode 100644 index 0000000..9006088 --- /dev/null +++ b/doc/aa-hiercopy.pod @@ -0,0 +1,59 @@ +=head1 NAME + +aa-hiercopy - Copy a directory structure recursively + +=head1 SYNOPSIS + +B<aa-hiercopy> [B<-D>] I<SOURCE> I<DESTINATION> + +=head1 OPTIONS + +=over + +=item B<-D, --double-output> + +Enable double-output mode. Instead of using stdout for regular output, and +stderr for warnings and errors, everything is sent both to stdout and stderr. +This is intended to redirect stderr to a log file, so full output can be both +shown on console and logged. + +=item B<-h, --help> + +Show help screen and exit. + +=item B<-V, --version> + +Show version information and exit. + +=back + +=head1 DESCRIPTION + +B<aa-hiercopy>(1) recursively copies I<SOURCE> to I<DESTINATION>, which is +created if it doesn't exist. The permissions are preserved. The owner and group +are preserved if the user is the superuser. + +Much like B<s6-hiercopy> this is simply a wrapper around a function of skalibs, +therefore it behaves very much the same. A notable difference however, is that +if I<SOURCE> is a symlink, B<aa-hiercopy>(1) will instead resolve it, whereas +B<s6-hiercopy> would simply copy the symlink itself. + +=head1 RETURN CODES + +Possible errors are: + +=over + +=item B<1> +Usage error + +=item B<2> +Failed to lstat I<SOURCE> + +=item B<3> +Failed to resolve symlink I<SOURCE> + +=item B<4> +Error during the copy + +=back diff --git a/package/modes b/package/modes index 21405c4..f972d27 100644 --- a/package/modes +++ b/package/modes @@ -3,6 +3,7 @@ aa-command 0755 aa-ctty 0755 aa-echo 0755 aa-enable 0755 +aa-hiercopy 0755 aa-incmdline 0755 aa-kill 0755 aa-mount 0755 diff --git a/package/targets.mak b/package/targets.mak index dbcabb6..ad1bcda 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -3,6 +3,7 @@ aa-chroot \ aa-ctty \ aa-echo \ aa-enable \ +aa-hiercopy \ aa-incmdline \ aa-kill \ aa-mount \ @@ -38,6 +39,7 @@ aa-command.1 \ aa-ctty.1 \ aa-echo.1 \ aa-enable.1 \ +aa-hiercopy.1 \ aa-incmdline.1 \ aa-kill.1 \ aa-mount.1 \ diff --git a/src/utils/aa-hiercopy.c b/src/utils/aa-hiercopy.c new file mode 100644 index 0000000..5865c45 --- /dev/null +++ b/src/utils/aa-hiercopy.c @@ -0,0 +1,105 @@ +/* + * anopa - Copyright (C) 2015-2018 Olivier Brunel + * + * aa-hiercopy.c + * Copyright (C) 2018 Olivier Brunel <jjk@jjacky.com> + * + * This file is part of anopa. + * + * anopa is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * anopa is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * anopa. If not, see http://www.gnu.org/licenses/ + */ + +#include <getopt.h> +#include <sys/stat.h> +#include <unistd.h> +#include <anopa/common.h> +#include <anopa/output.h> +#include <skalibs/djbunix.h> + +#ifndef NULL +#define NULL (void *) 0 +#endif + +static void +dieusage (int rc) +{ + aa_die_usage (rc, "SRC DST", + " -D, --double-output Enable double-output mode\n" + " -h, --help Show this help screen and exit\n" + " -V, --version Show version information and exit\n" + ); +} + +int +main (int argc, char * const argv[]) +{ + PROG = "aa-hiercopy"; + + for (;;) + { + struct option longopts[] = { + { "double-output", no_argument, NULL, 'D' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, 0, 0 } + }; + int c; + + c = getopt_long (argc, argv, "DhV", longopts, NULL); + if (c == -1) + break; + switch (c) + { + case 'D': + aa_set_double_output (1); + break; + + case 'h': + dieusage (0); + + case 'V': + aa_die_version (); + + default: + dieusage (1); + } + } + argc -= optind; + argv += optind; + + if (argc != 2) + dieusage (1); + + { + stralloc sa = STRALLOC_ZERO; + struct stat st; + char *sce = argv[0]; + + if (lstat (sce, &st) < 0) + aa_strerr_diefu2sys (2, "lstat ", sce); + if (S_ISLNK (st.st_mode)) + { + if (sarealpath (&sa, sce) < 0) + aa_strerr_diefu2x (3, "resolve symlink ", sce); + sce = sa.s; + } + + if (!hiercopy(sce, argv[1])) + aa_strerr_diefu4sys (4, "copy ", sce, " into ", argv[1]); + if (sa.a > 0) + stralloc_free (&sa); + } + + return 0; +} diff --git a/src/utils/deps-exe/aa-hiercopy b/src/utils/deps-exe/aa-hiercopy new file mode 100644 index 0000000..30987b4 --- /dev/null +++ b/src/utils/deps-exe/aa-hiercopy @@ -0,0 +1,2 @@ +${LIBANOPA} +-lskarnet