From owner-freebsd-bugs Thu Nov 18 6:50: 8 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id D4491153EF for ; Thu, 18 Nov 1999 06:50:03 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id GAA95649; Thu, 18 Nov 1999 06:50:03 -0800 (PST) (envelope-from gnats@FreeBSD.org) Date: Thu, 18 Nov 1999 06:50:03 -0800 (PST) Message-Id: <199911181450.GAA95649@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Alexander Langer Subject: Re: bin/14920: install(1) hangs when intalling files same directory. Reply-To: Alexander Langer Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/14920; it has been noted by GNATS. From: Alexander Langer To: okimoto@mrit.mei.co.jp Cc: freebsd-gnats-submit@FreeBSD.ORG Subject: Re: bin/14920: install(1) hangs when intalling files same directory. Date: Thu, 18 Nov 1999 15:49:55 +0100 ok. This patch seems nice. Please discard the old one. I also fixed a /dev/null error. Please see the thread on freebsd-bugs about this. Sheldon suggested to use realpath(), so I did. Usage-log: alex:~ $ mkdir test mkdir: test: File exists alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall foo test alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall foo test/foo alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall foo test/.. xinstall: foo and /usr/home/alex/foo are the same file alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall foo . xinstall: foo and /usr/home/alex/foo are the same file alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall foo ./ xinstall: foo and /usr/home/alex/foo are the same file alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall foo ./../alex xinstall: foo and /usr/home/alex/foo are the same file alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall ./foo ./../alex xinstall: ./foo and /usr/home/alex/foo are the same file alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall test test test.scm testdatei testwort.bak test.c testbla testwort alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall test/bar test xinstall: test/bar and /usr/home/alex/test/bar are the same file alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall test/bar test/.. alex:~ $ touch foo; /usr/obj/usr/src/usr.bin/xinstall/xinstall /dev/null test xinstall: Cannot install /dev/null to a directory ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ YES, I did it. I changed the error-msg. But I think, it's ok. alex:~ $ rm -rf bar ; /usr/obj/usr/src/usr.bin/xinstall/xinstall /dev/null bar ; ls -l bar -rwxr-xr-x 1 alex alex 0 18 Nov 15:45 bar* Patch: --- xinstall.c.old Wed Nov 17 20:32:40 1999 +++ xinstall.c Thu Nov 18 15:48:12 1999 @@ -90,7 +90,7 @@ int debug, docompare, docopy, dodir, dopreserve, dostrip, nommap, verbose; int mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; char *group, *owner, pathbuf[MAXPATHLEN]; -char pathbuf2[MAXPATHLEN]; +char pathbuf2[MAXPATHLEN], pathbuf3[MAXPATHLEN]; #define DIRECTORY 0x01 /* Tell install it's a directory. */ #define SETFLAGS 0x02 /* Tell install to set flags. */ @@ -319,7 +319,7 @@ u_long fset; u_int flags; { - struct stat from_sb, to_sb; + struct stat from_sb, to_sb, fileto_sb; int devnull, from_fd, to_fd, serrno; char *p, *old_to_name = 0; @@ -327,25 +327,35 @@ fprintf(stderr, "install: invoked without -C for %s to %s\n", from_name, to_name); + if (strcmp(from_name, _PATH_DEVNULL) == 0) { + from_sb.st_flags = 0; /* XXX */ + devnull = 1; + } else + devnull = 0; /* If try to install NULL file to a directory, fails. */ - if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) { + if (flags & DIRECTORY && devnull) + errx(EX_USAGE, "Cannot install %s to a directory", + _PATH_DEVNULL); + + if (flags & DIRECTORY) { + if (realpath(to_name, pathbuf2) == NULL) + errx(EX_OSERR, "%s", pathbuf2); + (void)snprintf(pathbuf3, sizeof(pathbuf3), + "%s/%s", pathbuf2, + (p = strrchr(from_name, '/')) ? ++p : from_name); + to_name = pathbuf3; /* target path is in pathbuf3 */ if (stat(from_name, &from_sb)) err(EX_OSERR, "%s", from_name); + if (stat(to_name, &fileto_sb) && errno != ENOENT) + err(EX_OSERR, "%s", to_name); if (!S_ISREG(from_sb.st_mode)) { errno = EFTYPE; err(EX_OSERR, "%s", from_name); } - /* Build the target path. */ - if (flags & DIRECTORY) { - (void)snprintf(pathbuf, sizeof(pathbuf), "%s/%s", - to_name, - (p = strrchr(from_name, '/')) ? ++p : from_name); - to_name = pathbuf; - } - devnull = 0; - } else { - from_sb.st_flags = 0; /* XXX */ - devnull = 1; + if (fileto_sb.st_dev == from_sb.st_dev && + fileto_sb.st_ino == from_sb.st_ino) + errx(EX_USAGE, + "%s and %s are the same file", from_name, pathbuf3); } if (docompare) { #### diff ends here So long, Alex -- I doubt, therefore I might be. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message