From: Dov Grobgeld Date: Sat, 27 May 2017 20:07:13 +0000 (+0300) Subject: Added --no-override option to rename. X-Git-Tag: v2.31-rc1~333^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fabb90676;p=thirdparty%2Futil-linux.git Added --no-override option to rename. --- diff --git a/misc-utils/rename.c b/misc-utils/rename.c index 502e888d79..fb99e8e2fb 100644 --- a/misc-utils/rename.c +++ b/misc-utils/rename.c @@ -53,7 +53,7 @@ static int string_replace(char *from, char *to, char *s, char *orig, char **newn return 0; } -static int do_symlink(char *from, char *to, char *s, int verbose, int noact) +static int do_symlink(char *from, char *to, char *s, int verbose, int noact, int nooverride) { char *newname = NULL, *target = NULL; int ret = 1; @@ -76,24 +76,36 @@ static int do_symlink(char *from, char *to, char *s, int verbose, int noact) target[sb.st_size] = '\0'; if (string_replace(from, to, target, target, &newname)) ret = 0; - else if (!noact && 0 > unlink(s)) { - warn(_("%s: unlink failed"), s); - ret = 2; - } else if (!noact && symlink(newname, s) != 0) { - warn(_("%s: symlinking to %s failed"), s, newname); - ret = 2; + + if (ret == 1 && nooverride && lstat(newname, &sb) == 0) { + if (verbose) + printf(_("Skipping existing link: `%s'\n"), newname); + + ret = 0; + } + + if (ret == 1) { + if (!noact && 0 > unlink(s)) { + warn(_("%s: unlink failed"), s); + ret = 2; + } else if (!noact && symlink(newname, s) != 0) { + warn(_("%s: symlinking to %s failed"), s, newname); + ret = 2; + } } if (verbose && (noact || ret == 1)) - printf("%s: `%s' -> `%s'\n", s, target, newname); + if (verbose) + printf("%s: `%s' -> `%s'\n", s, target, newname); free(newname); free(target); return ret; } -static int do_file(char *from, char *to, char *s, int verbose, int noact) +static int do_file(char *from, char *to, char *s, int verbose, int noact, int nooverride) { char *newname = NULL, *file=NULL; int ret = 1; + struct stat sb; if (strchr(from, '/') == NULL && strchr(to, '/') == NULL) file = strrchr(s, '/'); @@ -101,6 +113,10 @@ static int do_file(char *from, char *to, char *s, int verbose, int noact) file = s; if (string_replace(from, to, file, s, &newname)) return 0; + if (nooverride && stat(newname, &sb) == 0) { + printf(_("Skipping existing file: `%s'\n"), newname); + ret = 0; + } else if (!noact && rename(s, newname) != 0) { warn(_("%s: rename to %s failed"), s, newname); ret = 2; @@ -122,9 +138,10 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out) fputs(_("Rename files.\n"), out); fputs(USAGE_OPTIONS, out); - fputs(_(" -v, --verbose explain what is being done\n"), out); - fputs(_(" -s, --symlink act on the target of symlinks\n"), out); - fputs(_(" -n, --no-act do not make any changes\n"), out); + fputs(_(" -v, --verbose explain what is being done\n"), out); + fputs(_(" -s, --symlink act on the target of symlinks\n"), out); + fputs(_(" -n, --no-act do not make any changes\n"), out); + fputs(_(" -o, --no-override don't override existing files\n"), out); fputs(USAGE_SEPARATOR, out); fputs(USAGE_HELP, out); fputs(USAGE_VERSION, out); @@ -135,14 +152,15 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out) int main(int argc, char **argv) { char *from, *to; - int i, c, ret = 0, verbose = 0, noact = 0; - int (*do_rename)(char *from, char *to, char *s, int verbose, int noact) = do_file; + int i, c, ret = 0, verbose = 0, noact = 0, nooverride = 0; + int (*do_rename)(char *from, char *to, char *s, int verbose, int noact, int nooverride) = do_file; static const struct option longopts[] = { {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {"no-act", no_argument, NULL, 'n'}, + {"no-override", no_argument, NULL, 'o'}, {"symlink", no_argument, NULL, 's'}, {NULL, 0, NULL, 0} }; @@ -152,11 +170,14 @@ int main(int argc, char **argv) textdomain(PACKAGE); atexit(close_stdout); - while ((c = getopt_long(argc, argv, "vsVhn", longopts, NULL)) != -1) + while ((c = getopt_long(argc, argv, "vsVhno", longopts, NULL)) != -1) switch (c) { case 'n': noact = 1; /* fallthrough */ + case 'o': + nooverride = 1; + break; case 'v': verbose = 1; break; @@ -185,7 +206,7 @@ int main(int argc, char **argv) to = argv[1]; for (i = 2; i < argc; i++) - ret |= do_rename(from, to, argv[i], verbose, noact); + ret |= do_rename(from, to, argv[i], verbose, noact, nooverride); switch (ret) { case 0: