]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
Added --no-override option to rename.
authorDov Grobgeld <dov.grobgeld@gmail.com>
Sat, 27 May 2017 20:07:13 +0000 (23:07 +0300)
committerDov Grobgeld <dov.grobgeld@gmail.com>
Sat, 27 May 2017 20:26:32 +0000 (23:26 +0300)
misc-utils/rename.c

index 502e888d797eb45d05c61c655c1d5a96929b002d..fb99e8e2fb16e01fbc0ae98f6b315805e55e2d69 100644 (file)
@@ -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: