Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Nov 1999 06:50:03 -0800 (PST)
From:      Alexander Langer <alex@cichlids.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/14920: install(1) hangs when intalling files same directory.
Message-ID:  <199911181450.GAA95649@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/14920; it has been noted by GNATS.

From: Alexander Langer <alex@cichlids.com>
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199911181450.GAA95649>