Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mmv for openSUSE:Factory checked in at 2024-07-08 19:08:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mmv (Old) and /work/SRC/openSUSE:Factory/.mmv.new.2080 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mmv" Mon Jul 8 19:08:22 2024 rev:22 rq:1186034 version:2.6 Changes: -------- --- /work/SRC/openSUSE:Factory/mmv/mmv.changes 2024-01-03 12:30:38.143854950 +0100 +++ /work/SRC/openSUSE:Factory/.mmv.new.2080/mmv.changes 2024-07-08 19:08:43.059743772 +0200 @@ -1,0 +2,8 @@ +Sat Jul 6 08:17:50 UTC 2024 - Andrea Manzini <[email protected]> + +- update to 2.6: + * This release re-adds the âmadâ (âappendâ) command, and fixes how + the program name is checked when deciding which mode to run in. + * There is also a build system fix. + +------------------------------------------------------------------- Old: ---- mmv-2.5.1.tar.gz New: ---- mmv-2.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mmv.spec ++++++ --- /var/tmp/diff_new_pack.HHlkZs/_old 2024-07-08 19:08:43.695767033 +0200 +++ /var/tmp/diff_new_pack.HHlkZs/_new 2024-07-08 19:08:43.699767178 +0200 @@ -1,7 +1,7 @@ # # spec file for package mmv # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: mmv -Version: 2.5.1 +Version: 2.6 Release: 0 Summary: Move/Copy/Append/Link Multiple Files by Wildcard Patterns License: GPL-1.0-or-later ++++++ mmv-2.5.1.tar.gz -> mmv-2.6.tar.gz ++++++ ++++ 1857 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/Makefile.am new/mmv-2.6/Makefile.am --- old/mmv-2.5.1/Makefile.am 2023-08-08 12:44:11.000000000 +0200 +++ new/mmv-2.6/Makefile.am 2024-02-09 16:13:51.000000000 +0100 @@ -33,7 +33,7 @@ mmv_SOURCES = mmv.c cmdline.c cmdline.h mmv_LDADD = $(LDADD) -SYMLINKS = mcp$(EXEEXT) mln$(EXEEXT) +SYMLINKS = mcp$(EXEEXT) mln$(EXEEXT) mad$(EXEEXT) MAKELINKS = for n in $(SYMLINKS); do $(RM) $$n$(EXEEXT) && $(LN_S) mmv$(EXEEXT) $$n; done EXTRA_SRCS = opts.ggo @@ -52,8 +52,8 @@ mmv.o: cmdline.h -cmdline.h cmdline.c: opts.ggo - gengetopt < opts.ggo --unamed-opts +cmdline.h cmdline.c: $(top_srcdir)/opts.ggo + gengetopt < $(top_srcdir)/opts.ggo --unamed-opts all-local: mmv$(EXEEXT) $(MAKELINKS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/cmdline.c new/mmv-2.6/cmdline.c --- old/mmv-2.5.1/cmdline.c 2023-08-08 12:45:57.000000000 +0200 +++ new/mmv-2.6/cmdline.c 2024-02-09 16:14:38.000000000 +0100 @@ -25,7 +25,7 @@ #include "cmdline.h" -const char *gengetopt_args_info_purpose = "move/copy/link multiple files by wildcard patterns"; +const char *gengetopt_args_info_purpose = "move/copy/append/link multiple files by wildcard patterns"; const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [-m|-x|-r|-c|-o|-a|-l|-s] [-h] [-d|-p] [-g|-t] [-v|-n] FROM TO"; @@ -44,6 +44,7 @@ " -r, --rename rename source to target in same directory", " -c, --copy copy source to target, preserving source permissions", " -o, --overwrite overwrite target with source, preserving target permissions", + " -a, --append append contents of source file to target", " -l, --hardlink link target name to source file", " -s, --symlink symlink target name to source file", "\n Group: delete\n How to handle file deletions and overwrites", @@ -87,6 +88,7 @@ args_info->rename_given = 0 ; args_info->copy_given = 0 ; args_info->overwrite_given = 0 ; + args_info->append_given = 0 ; args_info->hardlink_given = 0 ; args_info->symlink_given = 0 ; args_info->force_given = 0 ; @@ -124,14 +126,15 @@ args_info->rename_help = gengetopt_args_info_help[7] ; args_info->copy_help = gengetopt_args_info_help[8] ; args_info->overwrite_help = gengetopt_args_info_help[9] ; - args_info->hardlink_help = gengetopt_args_info_help[10] ; - args_info->symlink_help = gengetopt_args_info_help[11] ; - args_info->force_help = gengetopt_args_info_help[13] ; - args_info->protect_help = gengetopt_args_info_help[14] ; - args_info->go_help = gengetopt_args_info_help[16] ; - args_info->terminate_help = gengetopt_args_info_help[17] ; - args_info->verbose_help = gengetopt_args_info_help[19] ; - args_info->dryrun_help = gengetopt_args_info_help[20] ; + args_info->append_help = gengetopt_args_info_help[10] ; + args_info->hardlink_help = gengetopt_args_info_help[11] ; + args_info->symlink_help = gengetopt_args_info_help[12] ; + args_info->force_help = gengetopt_args_info_help[14] ; + args_info->protect_help = gengetopt_args_info_help[15] ; + args_info->go_help = gengetopt_args_info_help[17] ; + args_info->terminate_help = gengetopt_args_info_help[18] ; + args_info->verbose_help = gengetopt_args_info_help[20] ; + args_info->dryrun_help = gengetopt_args_info_help[21] ; } @@ -268,6 +271,8 @@ write_into_file(outfile, "copy", 0, 0 ); if (args_info->overwrite_given) write_into_file(outfile, "overwrite", 0, 0 ); + if (args_info->append_given) + write_into_file(outfile, "append", 0, 0 ); if (args_info->hardlink_given) write_into_file(outfile, "hardlink", 0, 0 ); if (args_info->symlink_given) @@ -366,6 +371,7 @@ args_info->rename_given = 0 ; args_info->copy_given = 0 ; args_info->overwrite_given = 0 ; + args_info->append_given = 0 ; args_info->hardlink_given = 0 ; args_info->symlink_given = 0 ; @@ -585,6 +591,7 @@ { "rename", 0, NULL, 'r' }, { "copy", 0, NULL, 'c' }, { "overwrite", 0, NULL, 'o' }, + { "append", 0, NULL, 'a' }, { "hardlink", 0, NULL, 'l' }, { "symlink", 0, NULL, 's' }, { "force", 0, NULL, 'd' }, @@ -596,7 +603,7 @@ { 0, 0, 0, 0 } }; - c = getopt_long (argc, argv, "VhDmxrcolsdpgtvn", long_options, &option_index); + c = getopt_long (argc, argv, "VhDmxrcoalsdpgtvn", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -701,6 +708,21 @@ additional_error)) goto failure; + break; + case 'a': /* append contents of source file to target. */ + + if (args_info->mode_group_counter && override) + reset_group_mode (args_info); + args_info->mode_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->append_given), + &(local_args_info.append_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "append", 'a', + additional_error)) + goto failure; + break; case 'l': /* link target name to source file. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/cmdline.h new/mmv-2.6/cmdline.h --- old/mmv-2.5.1/cmdline.h 2023-08-08 12:45:57.000000000 +0200 +++ new/mmv-2.6/cmdline.h 2024-02-09 16:14:38.000000000 +0100 @@ -52,6 +52,7 @@ const char *rename_help; /**< @brief rename source to target in same directory help description. */ const char *copy_help; /**< @brief copy source to target, preserving source permissions help description. */ const char *overwrite_help; /**< @brief overwrite target with source, preserving target permissions help description. */ + const char *append_help; /**< @brief append contents of source file to target help description. */ const char *hardlink_help; /**< @brief link target name to source file help description. */ const char *symlink_help; /**< @brief symlink target name to source file help description. */ const char *force_help; /**< @brief perform file deletes and overwrites without confirmation help description. */ @@ -70,6 +71,7 @@ unsigned int rename_given ; /**< @brief Whether rename was given. */ unsigned int copy_given ; /**< @brief Whether copy was given. */ unsigned int overwrite_given ; /**< @brief Whether overwrite was given. */ + unsigned int append_given ; /**< @brief Whether append was given. */ unsigned int hardlink_given ; /**< @brief Whether hardlink was given. */ unsigned int symlink_given ; /**< @brief Whether symlink was given. */ unsigned int force_given ; /**< @brief Whether force was given. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/config.h.in new/mmv-2.6/config.h.in --- old/mmv-2.5.1/config.h.in 2023-08-08 13:08:18.000000000 +0200 +++ new/mmv-2.6/config.h.in 2024-02-09 16:14:34.000000000 +0100 @@ -70,6 +70,10 @@ #undef GNULIB_CANONICALIZE_LGPL /* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module dirname shall be considered present. */ +#undef GNULIB_DIRNAME + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending whether the gnulib module fscanf shall be considered present. */ #undef GNULIB_FSCANF @@ -197,6 +201,12 @@ /* Define to 1 when the gnulib module strerror should be tested. */ #undef GNULIB_TEST_STRERROR +/* Define to 1 when the gnulib module strndup should be tested. */ +#undef GNULIB_TEST_STRNDUP + +/* Define to 1 when the gnulib module strnlen should be tested. */ +#undef GNULIB_TEST_STRNLEN + /* Define to 1 when the gnulib module symlink should be tested. */ #undef GNULIB_TEST_SYMLINK @@ -298,6 +308,14 @@ don't. */ #undef HAVE_DECL_STRERROR_R +/* Define to 1 if you have the declaration of `strndup', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNDUP + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNLEN + /* Define to 1 if you have the declaration of `wcsdup', and to 0 if you don't. */ #undef HAVE_DECL_WCSDUP @@ -488,6 +506,9 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/configure.ac new/mmv-2.6/configure.ac --- old/mmv-2.5.1/configure.ac 2023-08-08 13:05:25.000000000 +0200 +++ new/mmv-2.6/configure.ac 2024-02-09 16:11:58.000000000 +0100 @@ -20,7 +20,7 @@ AC_PREREQ([2.71]) dnl Initialise autoconf and automake -AC_INIT([mmv],[2.5.1],[[email protected]],[],[https://github.com/rrthomas/mmv]) +AC_INIT([mmv],[2.6],[[email protected]],[],[https://github.com/rrthomas/mmv]) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([-Wall]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/Makefile.am new/mmv-2.6/lib/Makefile.am --- old/mmv-2.5.1/lib/Makefile.am 2023-08-08 13:02:52.000000000 +0200 +++ new/mmv-2.6/lib/Makefile.am 2023-11-01 18:32:20.000000000 +0100 @@ -35,6 +35,7 @@ # binary-io \ # bootstrap \ # close \ +# dirname \ # fprintf-posix \ # getopt-gnu \ # ignore-value \ @@ -166,6 +167,16 @@ ## end gnulib module close +## begin gnulib module dirname + +libgnu_a_SOURCES += dirname.c basename.c + +EXTRA_DIST += stripslash.c + +EXTRA_libgnu_a_SOURCES += stripslash.c + +## end gnulib module dirname + ## begin gnulib module dirname-lgpl libgnu_a_SOURCES += dirname-lgpl.c stripslash.c @@ -1759,6 +1770,24 @@ ## end gnulib module string +## begin gnulib module strndup + + +EXTRA_DIST += strndup.c + +EXTRA_libgnu_a_SOURCES += strndup.c + +## end gnulib module strndup + +## begin gnulib module strnlen + + +EXTRA_DIST += strnlen.c + +EXTRA_libgnu_a_SOURCES += strnlen.c + +## end gnulib module strnlen + ## begin gnulib module symlink @@ -2324,6 +2353,12 @@ ## end gnulib module xsize +## begin gnulib module xstrndup + +libgnu_a_SOURCES += xstrndup.h xstrndup.c + +## end gnulib module xstrndup + mostlyclean-local: mostlyclean-generic @for dir in '' $(MOSTLYCLEANDIRS); do \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/basename.c new/mmv-2.6/lib/basename.c --- old/mmv-2.5.1/lib/basename.c 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/lib/basename.c 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,58 @@ +/* basename.c -- return the last element in a file name + + Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2021 Free Software + Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "dirname.h" + +#include <string.h> +#include "xalloc.h" +#include "xstrndup.h" + +char * +base_name (char const *name) +{ + char const *base = last_component (name); + size_t length; + + /* If there is no last component, then name is a file system root or the + empty string. */ + if (! *base) + return xstrndup (name, base_len (name)); + + /* Collapse a sequence of trailing slashes into one. */ + length = base_len (base); + if (ISSLASH (base[length])) + length++; + + /* On systems with drive letters, "a/b:c" must return "./b:c" rather + than "b:c" to avoid confusion with a drive letter. On systems + with pure POSIX semantics, this is not an issue. */ + if (FILE_SYSTEM_PREFIX_LEN (base)) + { + char *p = xmalloc (length + 3); + p[0] = '.'; + p[1] = '/'; + memcpy (p + 2, base, length); + p[length + 2] = '\0'; + return p; + } + + /* Finally, copy the basename. */ + return xstrndup (base, length); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/dirname.c new/mmv-2.6/lib/dirname.c --- old/mmv-2.5.1/lib/dirname.c 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/lib/dirname.c 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,38 @@ +/* dirname.c -- return all but the last element in a file name + + Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2021 Free Software + Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "dirname.h" + +#include <stdlib.h> +#include <string.h> +#include "xalloc.h" + +/* Just like mdir_name (dirname-lgpl.c), except, rather than + returning NULL upon malloc failure, here, we report the + "memory exhausted" condition and exit. */ + +char * +dir_name (char const *file) +{ + char *result = mdir_name (file); + if (!result) + xalloc_die (); + return result; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/strndup.c new/mmv-2.6/lib/strndup.c --- old/mmv-2.5.1/lib/strndup.c 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/lib/strndup.c 2023-11-01 18:32:12.000000000 +0100 @@ -0,0 +1,36 @@ +/* A replacement function, for systems that lack strndup. + + Copyright (C) 1996-1998, 2001-2003, 2005-2007, 2009-2021 Free Software + Foundation, Inc. + + This program 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, or (at your option) any + later version. + + This program 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 this program; if not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <string.h> + +#include <stdlib.h> + +char * +strndup (char const *s, size_t n) +{ + size_t len = strnlen (s, n); + char *new = malloc (len + 1); + + if (new == NULL) + return NULL; + + new[len] = '\0'; + return memcpy (new, s, len); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/strnlen.c new/mmv-2.6/lib/strnlen.c --- old/mmv-2.5.1/lib/strnlen.c 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/lib/strnlen.c 2023-11-01 18:32:12.000000000 +0100 @@ -0,0 +1,30 @@ +/* Find the length of STRING, but scan at most MAXLEN characters. + Copyright (C) 2005-2007, 2009-2021 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <string.h> + +/* Find the length of STRING, but scan at most MAXLEN characters. + If no '\0' terminator is found in that many characters, return MAXLEN. */ + +size_t +strnlen (const char *string, size_t maxlen) +{ + const char *end = memchr (string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/xstrndup.c new/mmv-2.6/lib/xstrndup.c --- old/mmv-2.5.1/lib/xstrndup.c 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/lib/xstrndup.c 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,36 @@ +/* Duplicate a bounded initial segment of a string, with out-of-memory + checking. + Copyright (C) 2003, 2006-2007, 2009-2021 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "xstrndup.h" + +#include <string.h> +#include "xalloc.h" + +/* Return a newly allocated copy of at most N bytes of STRING. + In other words, return a copy of the initial segment of length N of + STRING. */ +char * +xstrndup (const char *string, size_t n) +{ + char *s = strndup (string, n); + if (! s) + xalloc_die (); + return s; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/lib/xstrndup.h new/mmv-2.6/lib/xstrndup.h --- old/mmv-2.5.1/lib/xstrndup.h 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/lib/xstrndup.h 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,23 @@ +/* Duplicate a bounded initial segment of a string, with out-of-memory + checking. + Copyright (C) 2003, 2009-2021 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see <https://www.gnu.org/licenses/>. */ + +#include <stddef.h> + +/* Return a newly allocated copy of at most N bytes of STRING. + In other words, return a copy of the initial segment of length N of + STRING. */ +extern char *xstrndup (const char *string, size_t n) _GL_ATTRIBUTE_MALLOC; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/m4/gnulib-cache.m4 new/mmv-2.6/m4/gnulib-cache.m4 --- old/mmv-2.5.1/m4/gnulib-cache.m4 2023-08-08 13:03:25.000000000 +0200 +++ new/mmv-2.6/m4/gnulib-cache.m4 2023-11-01 18:32:20.000000000 +0100 @@ -40,6 +40,7 @@ # binary-io \ # bootstrap \ # close \ +# dirname \ # fprintf-posix \ # getopt-gnu \ # ignore-value \ @@ -65,6 +66,7 @@ binary-io bootstrap close + dirname fprintf-posix getopt-gnu ignore-value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/m4/gnulib-comp.m4 new/mmv-2.6/m4/gnulib-comp.m4 --- old/mmv-2.5.1/m4/gnulib-comp.m4 2023-08-08 13:02:53.000000000 +0200 +++ new/mmv-2.6/m4/gnulib-comp.m4 2023-11-01 18:32:22.000000000 +0100 @@ -54,6 +54,7 @@ # Code from module chdir: # Code from module cloexec: # Code from module close: + # Code from module dirname: # Code from module dirname-lgpl: # Code from module double-slash-root: # Code from module dup2: @@ -148,6 +149,8 @@ # Code from module strerror: # Code from module strerror-override: # Code from module string: + # Code from module strndup: + # Code from module strnlen: # Code from module symlink: # Code from module sys_stat: # Code from module sys_types: @@ -163,6 +166,7 @@ # Code from module xalloc-die: # Code from module xalloc-oversized: # Code from module xsize: + # Code from module xstrndup: ]) # This macro should be invoked from ./configure.ac, in the section @@ -196,6 +200,7 @@ AC_LIBOBJ([close]) fi gl_UNISTD_MODULE_INDICATOR([close]) + gl_MODULE_INDICATOR([dirname]) gl_DOUBLE_SLASH_ROOT gl_FUNC_DUP2 if test $REPLACE_DUP2 = 1; then @@ -448,6 +453,17 @@ gl_PREREQ_SYS_H_WINSOCK2 fi gl_HEADER_STRING_H + gl_FUNC_STRNDUP + if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then + AC_LIBOBJ([strndup]) + fi + gl_STRING_MODULE_INDICATOR([strndup]) + gl_FUNC_STRNLEN + if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then + AC_LIBOBJ([strnlen]) + gl_PREREQ_STRNLEN + fi + gl_STRING_MODULE_INDICATOR([strnlen]) gl_FUNC_SYMLINK if test $HAVE_SYMLINK = 0 || test $REPLACE_SYMLINK = 1; then AC_LIBOBJ([symlink]) @@ -477,6 +493,7 @@ gl_MODULE_INDICATOR([xalloc]) gl_MODULE_INDICATOR([xalloc-die]) gl_XSIZE + gl_XSTRNDUP # End of code from modules m4_ifval(gl_LIBSOURCES_LIST, [ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || @@ -629,6 +646,7 @@ lib/attribute.h lib/basename-lgpl.c lib/basename-lgpl.h + lib/basename.c lib/binary-io.c lib/binary-io.h lib/c++defs.h @@ -638,6 +656,7 @@ lib/cloexec.h lib/close.c lib/dirname-lgpl.c + lib/dirname.c lib/dirname.h lib/dup2.c lib/eloop-threshold.h @@ -755,6 +774,8 @@ lib/strerror.c lib/string.in.h lib/stripslash.c + lib/strndup.c + lib/strnlen.c lib/symlink.c lib/sys_stat.in.h lib/sys_types.in.h @@ -774,6 +795,8 @@ lib/xmalloc.c lib/xsize.c lib/xsize.h + lib/xstrndup.c + lib/xstrndup.h m4/00gnulib.m4 m4/__inline.m4 m4/absolute-header.m4 @@ -865,6 +888,8 @@ m4/strdup.m4 m4/strerror.m4 m4/string_h.m4 + m4/strndup.m4 + m4/strnlen.m4 m4/symlink.m4 m4/sys_socket_h.m4 m4/sys_stat_h.m4 @@ -881,5 +906,6 @@ m4/write.m4 m4/xalloc.m4 m4/xsize.m4 + m4/xstrndup.m4 m4/zzgnulib.m4 ]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/m4/strndup.m4 new/mmv-2.6/m4/strndup.m4 --- old/mmv-2.5.1/m4/strndup.m4 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/m4/strndup.m4 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,58 @@ +# strndup.m4 serial 22 +dnl Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRNDUP], +[ + dnl Persuade glibc <string.h> to declare strndup(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_CHECK_DECLS_ONCE([strndup]) + AC_CHECK_FUNCS_ONCE([strndup]) + if test $ac_cv_have_decl_strndup = no; then + HAVE_DECL_STRNDUP=0 + fi + + if test $ac_cv_func_strndup = yes; then + HAVE_STRNDUP=1 + # AIX 4.3.3, AIX 5.1 have a function that fails to add the terminating '\0'. + AC_CACHE_CHECK([for working strndup], [gl_cv_func_strndup_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[#include <string.h> + #include <stdlib.h>]], [[ +#if !HAVE_DECL_STRNDUP + extern + #ifdef __cplusplus + "C" + #endif + char *strndup (const char *, size_t); +#endif + int result; + char *s; + s = strndup ("some longer string", 15); + free (s); + s = strndup ("shorter string", 13); + result = s[13] != '\0'; + free (s); + return result;]])], + [gl_cv_func_strndup_works=yes], + [gl_cv_func_strndup_works=no], + [ +changequote(,)dnl + case $host_os in + aix | aix[3-6]*) gl_cv_func_strndup_works="guessing no";; + *) gl_cv_func_strndup_works="guessing yes";; + esac +changequote([,])dnl + ])]) + case $gl_cv_func_strndup_works in + *no) REPLACE_STRNDUP=1 ;; + esac + else + HAVE_STRNDUP=0 + fi +]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/m4/strnlen.m4 new/mmv-2.6/m4/strnlen.m4 --- old/mmv-2.5.1/m4/strnlen.m4 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/m4/strnlen.m4 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,30 @@ +# strnlen.m4 serial 13 +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRNLEN], +[ + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + + dnl Persuade glibc <string.h> to declare strnlen(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([strnlen]) + if test $ac_cv_have_decl_strnlen = no; then + HAVE_DECL_STRNLEN=0 + else + m4_pushdef([AC_LIBOBJ], [:]) + dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). + AC_FUNC_STRNLEN + m4_popdef([AC_LIBOBJ]) + if test $ac_cv_func_strnlen_working = no; then + REPLACE_STRNLEN=1 + fi + fi +]) + +# Prerequisites of lib/strnlen.c. +AC_DEFUN([gl_PREREQ_STRNLEN], [:]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/m4/xstrndup.m4 new/mmv-2.6/m4/xstrndup.m4 --- old/mmv-2.5.1/m4/xstrndup.m4 1970-01-01 01:00:00.000000000 +0100 +++ new/mmv-2.6/m4/xstrndup.m4 2023-11-01 18:22:09.000000000 +0100 @@ -0,0 +1,15 @@ +# xstrndup.m4 serial 2 +dnl Copyright (C) 2003, 2009-2021 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_XSTRNDUP], +[ + gl_PREREQ_XSTRNDUP +]) + +# Prerequisites of lib/xstrndup.c. +AC_DEFUN([gl_PREREQ_XSTRNDUP], [ + : +]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/mmv-include.man new/mmv-2.6/mmv-include.man --- old/mmv-2.5.1/mmv-include.man 2023-02-04 23:43:50.000000000 +0100 +++ new/mmv-2.6/mmv-include.man 2024-02-09 16:11:58.000000000 +0100 @@ -1,10 +1,10 @@ [NAME] -mmv - move/copy/link multiple files by wildcard patterns +mmv - move/copy/append/link multiple files by wildcard patterns [>DESCRIPTION] .PP .I Mmv -moves (or copies or links, as specified) +moves (or copies, appends, or links, as specified) each source file matching a .I from pattern to the target name specified by the @@ -40,7 +40,7 @@ .PP Whether .I mmv -moves, copies, or links +moves, copies, appends, or links is governed by the first set of options given above. If none of these are specified, @@ -54,6 +54,8 @@ .br mcp \-\-copy .br + mad \-\-append +.br mln \-\-hardlink .PP The task option choices are: @@ -94,6 +96,16 @@ and the execute permission bits copied from the source file. In either case, the file modification time is set to the current time. .TP +\fB\-\-append\fR: +append contents of source file to target name. +Target file modification time is set to the current time. +If target file does not exist, +it is created with permission bits +set as under \-\-overwrite. +Unlike all other options, \-\-append allows multiple source files to have the +same target name, e.g. "mmv \-a \\*.c big" will append all ".c" files to "big". +Chains and cycles are also allowed, so "mmv \-a f f" will double up "f". +.TP \fB\-\-hardlink\fR: link target name to source file. Both must be on the same device, @@ -272,10 +284,11 @@ .I Mmv detects chains and cycles regardless of the order in which their constituent actions are actually given. -Where allowed, i.e. in moving and renaming files, +Where allowed, i.e. in moving, renaming, and appending files, chains and cycles are handled gracefully, by performing them in the proper order. -Cycles are broken by first renaming one of the files to a temporary name. +Cycles are broken by first renaming one of the files to a temporary name +(or just remembering its original size when doing appends). .ce Collisions and Deletions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/mmv.1 new/mmv-2.6/mmv.1 --- old/mmv-2.5.1/mmv.1 2023-08-08 12:51:57.000000000 +0200 +++ new/mmv-2.6/mmv.1 2024-02-09 16:14:38.000000000 +0100 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH MMV "1" "August 2023" "mmv 2.5" "User Commands" +.TH MMV "1" "February 2024" "mmv 2.5" "User Commands" .SH NAME -mmv - move/copy/link multiple files by wildcard patterns +mmv - move/copy/append/link multiple files by wildcard patterns .SH SYNOPSIS .B mmv [\fI\,-m|-x|-r|-c|-o|-a|-l|-s\/\fR] [\fI\,-h\/\fR] [\fI\,-d|-p\/\fR] [\fI\,-g|-t\/\fR] [\fI\,-v|-n\/\fR] \fI\,FROM TO\/\fR @@ -68,7 +68,7 @@ only report which actions would be performed .PP .I Mmv -moves (or copies or links, as specified) +moves (or copies, appends, or links, as specified) each source file matching a .I from pattern to the target name specified by the @@ -104,7 +104,7 @@ .PP Whether .I mmv -moves, copies, or links +moves, copies, appends, or links is governed by the first set of options given above. If none of these are specified, @@ -118,6 +118,8 @@ .br mcp \-\-copy .br + mad \-\-append +.br mln \-\-hardlink .PP The task option choices are: @@ -158,6 +160,16 @@ and the execute permission bits copied from the source file. In either case, the file modification time is set to the current time. .TP +\fB\-\-append\fR: +append contents of source file to target name. +Target file modification time is set to the current time. +If target file does not exist, +it is created with permission bits +set as under \-\-overwrite. +Unlike all other options, \-\-append allows multiple source files to have the +same target name, e.g. "mmv \-a \\*.c big" will append all ".c" files to "big". +Chains and cycles are also allowed, so "mmv \-a f f" will double up "f". +.TP \fB\-\-hardlink\fR: link target name to source file. Both must be on the same device, @@ -336,10 +348,11 @@ .I Mmv detects chains and cycles regardless of the order in which their constituent actions are actually given. -Where allowed, i.e. in moving and renaming files, +Where allowed, i.e. in moving, renaming, and appending files, chains and cycles are handled gracefully, by performing them in the proper order. -Cycles are broken by first renaming one of the files to a temporary name. +Cycles are broken by first renaming one of the files to a temporary name +(or just remembering its original size when doing appends). .ce Collisions and Deletions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/mmv.c new/mmv-2.6/mmv.c --- old/mmv-2.5.1/mmv.c 2023-08-08 12:51:50.000000000 +0200 +++ new/mmv-2.6/mmv.c 2024-02-09 16:11:58.000000000 +0100 @@ -54,6 +54,7 @@ #include "progname.h" #include "binary-io.h" +#include "dirname.h" #include "pathmax.h" #include "xalloc.h" #ifndef _WIN32 @@ -78,6 +79,7 @@ #define NORMMOVE 0x008 #define XMOVE 0x010 #define DIRMOVE 0x020 +#define APPEND 0x040 #define HARDLINK 0x100 #define SYMLINK 0x200 @@ -86,6 +88,7 @@ #define LINK (HARDLINK | SYMLINK) static char COPYNAME[] = "mcp"; +static char APPENDNAME[] = "mad"; static char LINKNAME[] = "mln"; #define ASKDEL 0 @@ -865,7 +868,7 @@ if ((ffrom->fi_stflags & FI_LINKERR) && !(op & (MOVE | SYMLINK))) printf("%s -> %s : source file is a badly aimed symbolic link.\n", pathbuf, fullrep); - else if ((op & COPY) && access(pathbuf, R_OK)) + else if ((op & (COPY | APPEND)) && access(pathbuf, R_OK)) printf("%s -> %s : no read permission for source file.\n", pathbuf, fullrep); else if ( @@ -1408,7 +1411,7 @@ char *t = fto->fi_name, *f = p->r_ffrom->fi_name; char *hnf = hfrom->h_name, *hnt = hto->h_name; - if (delstyle == NODEL && !(p->r_flags & R_DELOK)) + if (delstyle == NODEL && !(p->r_flags & R_DELOK) && !(op & APPEND)) printf("%s%s -> %s%s : old %s%s would have to be %s.\n", hnf, f, hnt, t, hnt, t, (op & OVERWRITE) ? "overwritten" : "deleted"); @@ -1419,12 +1422,12 @@ fto->fi_stflags & FI_ISDIR ) printf("%s%s -> %s%s : %s%s%s is a directory.\n", - hnf, f, hnt, t, "old ", hnt, t); - else if ((fto->fi_stflags & FI_NODEL) && !(op & OVERWRITE)) + hnf, f, hnt, t, (op & APPEND) ? "" : "old ", hnt, t); + else if ((fto->fi_stflags & FI_NODEL) && !(op & (APPEND | OVERWRITE))) printf("%s%s -> %s%s : old %s%s lacks delete permission.\n", hnf, f, hnt, t, hnt, t); else if ( - (op & OVERWRITE) && + (op & (APPEND | OVERWRITE)) && !fwritable(hnt, fto) ) { printf("%s%s -> %s%s : %s%s %s.\n", @@ -1471,7 +1474,7 @@ p->r_flags & R_ISALIASED ? '=' : '-', p->r_flags & R_ISCYCLE ? '^' : '>', p->r_hto->h_name, p->r_nto, - (p->r_fdel != NULL) ? " (*)" : ""); + (p->r_fdel != NULL && !(op & APPEND)) ? " (*)" : ""); } } @@ -1489,6 +1492,22 @@ return(first != p); } +static long appendalias(REP *first, REP *p, int *pprintaliased) +{ + long ret = 0l; + + struct stat fstat; + + if (stat(fullrep, &fstat)) { + fprintf(stderr, "append cycle stat on %s has failed.\n", fullrep); + *pprintaliased = snap(first, p); + } + else + ret = fstat.st_size; + + return(ret); +} + static int movealias(REP *first, REP *p, int *pprintaliased) { char *fstart; @@ -1515,7 +1534,7 @@ #define IRWMASK (S_IRUSR | S_IWUSR) #define RWMASK (IRWMASK | (IRWMASK >> 3) | (IRWMASK >> 6)) -static int copy(FILEINFO *ff) +static int copy(FILEINFO *ff, off_t len) { char buf[BUFSIZ]; int f, t, mode; @@ -1526,19 +1545,32 @@ if ((f = open(pathbuf, O_RDONLY | O_BINARY, 0)) < 0) return(-1); - perm = (op & OVERWRITE) ? + perm = (op & (APPEND | OVERWRITE)) ? (~oldumask & RWMASK) | (ff->fi_mode & (mode_t)~RWMASK) : ff->fi_mode; - mode = O_CREAT | O_TRUNC | O_WRONLY; + mode = O_CREAT | (op & APPEND ? 0 : O_TRUNC) | O_WRONLY; t = open(fullrep, mode, perm); if (t < 0) { close(f); return(-1); } - while ((k = read(f, buf, BUFSIZ)) > 0 && write(t, buf, (size_t)k) == k) - ; - if (!(op & OVERWRITE)) + if (op & APPEND) + lseek(t, (off_t)0, SEEK_END); + if ((op & APPEND) && len != (off_t)-1) { + while ( + len != 0 && + (k = read(f, buf, (len > BUFSIZ) ? BUFSIZ : (size_t)len)) > 0 && + write(t, buf, (size_t)k) == k + ) + len -= k; + if (len == 0) + k = 0; + } + else + while ((k = read(f, buf, BUFSIZ)) > 0 && write(t, buf, (size_t)k) == k) + ; + if (!(op & (APPEND | OVERWRITE))) if ( stat(pathbuf, &fstat) || ( @@ -1553,7 +1585,8 @@ close(f); close(t); if (k != 0) { - unlink(fullrep); + if (!(op & APPEND)) + unlink(fullrep); return(-1); } return(0); @@ -1570,7 +1603,7 @@ static int copymove(REP *p) { - return(copy(p->r_ffrom) || myunlink(pathbuf)); + return(copy(p->r_ffrom, -1L) || myunlink(pathbuf)); } static void doreps(void) @@ -1579,6 +1612,7 @@ unsigned k; int printaliased = 0, alias = 0; REP *first, *p; + long aliaslen = 0l; signal(SIGINT, breakrep); @@ -1600,20 +1634,25 @@ p->r_hto->h_di->di_flags &= ~DI_NONEXISTENT; } strcat(fullrep, p->r_nto); - if (!noex && (p->r_flags & R_ISCYCLE)) - alias = movealias(first, p, &printaliased); + if (!noex && (p->r_flags & R_ISCYCLE)) { + if (op & APPEND) + aliaslen = appendalias(first, p, &printaliased); + else + alias = movealias(first, p, &printaliased); + } strcpy(pathbuf, p->r_hfrom->h_name); fstart = pathbuf + strlen(pathbuf); - if (p->r_flags & R_ISALIASED) + if ((p->r_flags & R_ISALIASED) && !(op & APPEND)) sprintf(fstart, "%s%03d", TEMP, alias); else strcpy(fstart, p->r_ffrom->fi_name); if (!noex) { - if (p->r_fdel != NULL && !(op & OVERWRITE)) + if (p->r_fdel != NULL && !(op & (APPEND | OVERWRITE))) myunlink(fullrep); if ( - (op & COPY) ? - copy(p->r_ffrom) : + (op & (COPY | APPEND)) ? + copy(p->r_ffrom, + p->r_flags & R_ISALIASED ? aliaslen : -1L) : (op & HARDLINK) ? link(pathbuf, fullrep) : (op & SYMLINK) ? @@ -1637,7 +1676,7 @@ p->r_flags & R_ISALIASED ? '=' : '-', p->r_flags & R_ISCYCLE ? '^' : '>', fullrep, - (p->r_fdel != NULL) ? " (*)" : "", + (p->r_fdel != NULL && !(op & APPEND)) ? " (*)" : "", noex ? "" : " : done"); } } @@ -1711,14 +1750,20 @@ op = NORMCOPY; else if (args_info.overwrite_given != 0) op = OVERWRITE; + else if (args_info.append_given != 0) + op = APPEND; else if (args_info.hardlink_given != 0) op = HARDLINK; else if (args_info.symlink_given != 0) op = SYMLINK; else { - if (strcmp(program_name, COPYNAME) == 0) + const char *name = basename(program_name); + + if (strcmp(name, COPYNAME) == 0) op = NORMCOPY; - else if (strcmp(program_name, LINKNAME) == 0) + else if (strcmp(name, APPENDNAME) == 0) + op = APPEND; + else if (strcmp(name, LINKNAME) == 0) op = HARDLINK; else op = XMOVE; @@ -1747,13 +1792,14 @@ } domatch(frompat, topat); - checkcollisions(); + if (!(op & APPEND)) + checkcollisions(); findorder(); if (op & (COPY | LINK)) nochains(); scandeletes(baddel); goonordie(); - if (delstyle == ASKDEL) + if (!(op & APPEND) && delstyle == ASKDEL) scandeletes(skipdel); doreps(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/mmv-2.5.1/opts.ggo new/mmv-2.6/opts.ggo --- old/mmv-2.5.1/opts.ggo 2023-08-08 12:44:11.000000000 +0200 +++ new/mmv-2.6/opts.ggo 2024-02-09 16:11:58.000000000 +0100 @@ -1,5 +1,5 @@ # gengetopt for mmv -purpose "move/copy/link multiple files by wildcard patterns" +purpose "move/copy/append/link multiple files by wildcard patterns" usage " [-m|-x|-r|-c|-o|-a|-l|-s] [-h] [-d|-p] [-g|-t] [-v|-n] FROM TO" description "The FROM pattern is a shell glob pattern, in which `*' stands for any number @@ -25,6 +25,7 @@ groupoption "rename" r "rename source to target in same directory" group="mode" groupoption "copy" c "copy source to target, preserving source permissions" group="mode" groupoption "overwrite" o "overwrite target with source, preserving target permissions" group="mode" +groupoption "append" a "append contents of source file to target" group="mode" groupoption "hardlink" l "link target name to source file" group="mode" groupoption "symlink" s "symlink target name to source file" group="mode"
