Date: Thu, 3 Aug 2000 00:53:36 -0700 (PDT) From: eps@sirius.com (Eric P. Scott) To: freebsd-hackers@freebsd.org Subject: fixing longstanding cp -Rp misbehavior Message-ID: <200008030753.AAA62717@mail1.sirius.com>
next in thread | raw e-mail | index | archive | help
I want to make an "exact" copy of a directory tree (as far as practical). I was hoping cp -Rp would do the trick (assuming I have no hard-linked files), but it fails on several counts: 1) modification times on directories get smashed 2) UNIX (er, "local") domain sockets aren't copied 3) unless run as root, can't copy _from_ write-protected directories This context diff (against /usr/src/bin/cp/ from 3.5.1-RELEASE) is intended as a starting point for discussion; if you can come up with something more elegant, by all means commit that instead. -=EPS=- ------- *** cp.c.orig Sat Dec 11 12:33:31 1999 --- cp.c *************** *** 271,278 **** warnx("%s: directory causes a cycle", curr->fts_path); badcp = rval = 1; continue; - case FTS_DP: /* Ignore, continue. */ - continue; } /* --- 271,276 ---- *************** *** 330,335 **** --- 328,339 ---- STRIP_TRAILING_SLASH(to); } + if (curr->fts_info == FTS_DP) { + if (pflag && setfile(curr->fts_statp, 0)) + badcp = rval = 1; + continue; + } + /* Not an error but need to remember it happened */ if (stat(to.p_path, &to_stat) == -1) dne = 1; *************** *** 388,398 **** * umask; arguably wrong, but it's been that way * forever. */ ! if (pflag && setfile(curr->fts_statp, 0)) ! badcp = rval = 1; ! else if (dne) ! (void)chmod(to.p_path, ! curr->fts_statp->st_mode); break; case S_IFBLK: case S_IFCHR: --- 392,399 ---- * umask; arguably wrong, but it's been that way * forever. */ ! if (!pflag && dne) (void)chmod(to.p_path, ! curr->fts_statp->st_mode); break; case S_IFBLK: case S_IFCHR: *************** *** 407,412 **** --- 408,422 ---- case S_IFIFO: if (Rflag) { if (copy_fifo(curr->fts_statp, !dne)) + badcp = rval = 1; + } else { + if (copy_file(curr, dne)) + badcp = rval = 1; + } + break; + case S_IFSOCK: + if (Rflag) { + if (copy_socket(curr->fts_statp, !dne)) badcp = rval = 1; } else { if (copy_file(curr, dne)) *** extern.h.orig Sun Aug 29 07:11:34 1999 --- extern.h *************** *** 50,55 **** --- 50,56 ---- int copy_fifo __P((struct stat *, int)); int copy_file __P((FTSENT *, int)); int copy_link __P((FTSENT *, int)); + int copy_socket __P((struct stat *, int)); int copy_special __P((struct stat *, int)); int setfile __P((struct stat *, int)); void usage __P((void)); *** utils.c.orig Sat Dec 11 12:33:31 1999 --- utils.c *************** *** 44,49 **** --- 44,51 ---- #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED #include <sys/mman.h> #endif + #include <sys/socket.h> + #include <sys/un.h> #include <err.h> #include <errno.h> *************** *** 51,56 **** --- 53,59 ---- #include <fts.h> #include <stdio.h> #include <sysexits.h> + #include <string.h> #include <unistd.h> #include "extern.h" *************** *** 255,260 **** --- 258,302 ---- warn("mknod: %s", to.p_path); return (1); } + return (pflag ? setfile(from_stat, 0) : 0); + } + + int + copy_socket(from_stat, exists) + struct stat *from_stat; + int exists; + { + register int s, n; + union { + char data[256]; + struct sockaddr_un un; + } u; + + if (exists && unlink(to.p_path)) { + warn("unlink: %s", to.p_path); + return (1); + } + if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { + warn("socket: %s", to.p_path); + return (1); + } + bzero((void *)&u, sizeof u); + u.un.sun_len = 255; + u.un.sun_family = AF_UNIX; + if ((n = strlen(to.p_path)) > + sizeof u - (sizeof u.un - sizeof u.un.sun_path)) { + warn("bind: %s", to.p_path); + (void)close(s); + return (1); + } + (void)strcpy(u.un.sun_path, to.p_path); + if (bind(s, (struct sockaddr *)&u.un, + sizeof u.un - sizeof u.un.sun_path + n)) { + warn("bind: %s", to.p_path); + (void)close(s); + return (1); + } + (void)close(s); return (pflag ? setfile(from_stat, 0) : 0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200008030753.AAA62717>