Revert earlier revert.
authormartijn <martijn@openbsd.org>
Fri, 7 Sep 2018 13:46:33 +0000 (13:46 +0000)
committermartijn <martijn@openbsd.org>
Fri, 7 Sep 2018 13:46:33 +0000 (13:46 +0000)
It turned out the issue was a badly applied diff on stsp@'s machine.

OK stsp@

bin/cp/cp.c
bin/cp/utils.c

index 282defd..c2f947a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cp.c,v 1.50 2018/09/07 11:01:22 stsp Exp $    */
+/*     $OpenBSD: cp.c,v 1.51 2018/09/07 13:46:33 martijn Exp $ */
 /*     $NetBSD: cp.c,v 1.14 1995/09/07 06:14:51 jtc Exp $      */
 
 /*
@@ -264,7 +264,7 @@ copy(char *argv[], enum op type, int fts_options)
        struct stat to_stat;
        FTS *ftsp;
        FTSENT *curr;
-       int base, nlen, rval;
+       int base, cval, nlen, rval;
        char *p, *target_mid;
        base = 0;
 
@@ -395,9 +395,9 @@ copy(char *argv[], enum op type, int fts_options)
 
                switch (curr->fts_statp->st_mode & S_IFMT) {
                case S_IFLNK:
-                       if (copy_link(curr, !fts_dne(curr)))
+                       if ((cval = copy_link(curr, !fts_dne(curr))) == 1)
                                rval = 1;
-                       else if (vflag)
+                       if (!cval && vflag)
                                (void)fprintf(stdout, "%s -> %s\n",
                                    curr->fts_path, to.p_path);
                        break;
@@ -430,36 +430,40 @@ copy(char *argv[], enum op type, int fts_options)
                case S_IFBLK:
                case S_IFCHR:
                        if (Rflag) {
-                               if (copy_special(curr->fts_statp,
-                                   !fts_dne(curr)))
+                               if ((cval = copy_special(curr->fts_statp,
+                                   !fts_dne(curr))) == 1)
                                        rval = 1;
                        } else
-                               if (copy_file(curr, fts_dne(curr)))
+                               if ((cval = copy_file(curr, !fts_dne(curr))) == 1)
                                        rval = 1;
-                       if (!rval && vflag)
+                       if (!cval && vflag)
                                (void)fprintf(stdout, "%s -> %s\n",
                                    curr->fts_path, to.p_path);
+                       cval = 0;
                        break;
                case S_IFIFO:
                        if (Rflag) {
-                               if (copy_fifo(curr->fts_statp, !fts_dne(curr)))
+                               if ((cval = copy_fifo(curr->fts_statp,
+                                   !fts_dne(curr))) == 1)
                                        rval = 1;
                        } else
-                               if (copy_file(curr, fts_dne(curr)))
+                               if ((cval = copy_file(curr, !fts_dne(curr))) == 1)
                                        rval = 1;
-                       if (!rval && vflag)
+                       if (!cval && vflag)
                                (void)fprintf(stdout, "%s -> %s\n",
                                    curr->fts_path, to.p_path);
+                       cval = 0;
                        break;
                case S_IFSOCK:
                        warnc(EOPNOTSUPP, "%s", curr->fts_path);
                        break;
                default:
-                       if (copy_file(curr, fts_dne(curr)))
+                       if ((cval = copy_file(curr, !fts_dne(curr))) == 1)
                                rval = 1;
-                       else if (vflag)
+                       if (!cval && vflag)
                                (void)fprintf(stdout, "%s -> %s\n",
                                    curr->fts_path, to.p_path);
+                       cval = 0;
                        break;
                }
        }
index ef4d1f1..dc86deb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: utils.c,v 1.45 2018/09/07 11:01:22 stsp Exp $ */
+/*     $OpenBSD: utils.c,v 1.46 2018/09/07 13:46:33 martijn Exp $      */
 /*     $NetBSD: utils.c,v 1.6 1997/02/26 14:40:51 cgd Exp $    */
 
 /*-
 
 #include "extern.h"
 
+int copy_overwrite(void);
+
 int
-copy_file(FTSENT *entp, int dne)
+copy_file(FTSENT *entp, int exists)
 {
        static char *buf;
        static char *zeroes;
        struct stat to_stat, *fs;
-       int ch, checkch, from_fd, rcount, rval, to_fd, wcount;
+       int from_fd, rcount, rval, to_fd, wcount;
 #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
        char *p;
 #endif
@@ -80,28 +82,21 @@ copy_file(FTSENT *entp, int dne)
         * In -f (force) mode, we always unlink the destination first
         * if it exists.  Note that -i and -f are mutually exclusive.
         */
-       if (!dne && fflag)
+       if (exists && fflag)
                (void)unlink(to.p_path);
 
        /*
-        * If the file exists and we're interactive, verify with the user.
         * If the file DNE, set the mode to be the from file, minus setuid
         * bits, modified by the umask; arguably wrong, but it makes copying
         * executables work right and it's been that way forever.  (The
         * other choice is 666 or'ed with the execute bits on the from file
         * modified by the umask.)
         */
-       if (!dne && !fflag) {
-               if (iflag) {
-                       (void)fprintf(stderr, "overwrite %s? ", to.p_path);
-                       checkch = ch = getchar();
-                       while (ch != '\n' && ch != EOF)
-                               ch = getchar();
-                       if (checkch != 'y' && checkch != 'Y') {
-                               (void)close(from_fd);
-                               return (0);
-                       }
-               }
+       if (exists && !fflag) {
+               if (!copy_overwrite()) {
+                       (void)close(from_fd);
+                       return 2;
+               }
                to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
        } else
                to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
@@ -179,7 +174,7 @@ copy_file(FTSENT *entp, int dne)
         */
 #define        RETAINBITS \
        (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
-       if (!pflag && dne &&
+       if (!pflag && !exists &&
            fs->st_mode & (S_ISUID | S_ISGID) && fs->st_uid == myuid) {
                if (fstat(to_fd, &to_stat)) {
                        warn("%s", to.p_path);
@@ -204,6 +199,8 @@ copy_link(FTSENT *p, int exists)
        int len;
        char name[PATH_MAX];
 
+       if (exists && !copy_overwrite())
+               return (2);
        if ((len = readlink(p->fts_path, name, sizeof(name)-1)) == -1) {
                warn("readlink: %s", p->fts_path);
                return (1);
@@ -223,6 +220,8 @@ copy_link(FTSENT *p, int exists)
 int
 copy_fifo(struct stat *from_stat, int exists)
 {
+       if (exists && !copy_overwrite())
+               return (2);
        if (exists && unlink(to.p_path)) {
                warn("unlink: %s", to.p_path);
                return (1);
@@ -237,6 +236,8 @@ copy_fifo(struct stat *from_stat, int exists)
 int
 copy_special(struct stat *from_stat, int exists)
 {
+       if (exists && !copy_overwrite())
+               return (2);
        if (exists && unlink(to.p_path)) {
                warn("unlink: %s", to.p_path);
                return (1);
@@ -248,6 +249,24 @@ copy_special(struct stat *from_stat, int exists)
        return (pflag ? setfile(from_stat, -1) : 0);
 }
 
+/*
+ * If the file exists and we're interactive, verify with the user.
+ */
+int
+copy_overwrite(void)
+{
+       int ch, checkch;
+
+       if (iflag) {
+               (void)fprintf(stderr, "overwrite %s? ", to.p_path);
+               checkch = ch = getchar();
+               while (ch != '\n' && ch != EOF)
+                       ch = getchar();
+               if (checkch != 'y' && checkch != 'Y')
+                       return (0);
+       }
+       return 1;
+}
 
 int
 setfile(struct stat *fs, int fd)