Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Nov 1999 13:00:02 -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:  <199911172100.NAA25431@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: Wed, 17 Nov 1999 21:51:32 +0100

 I've done a patch to xinstall, that detects if the source-file is the
 same as the destination file, also if they are in the same directory:
 
 alex:~ $ touch foo bar
 alex:~ $ install foo bar .
 install: foo and ./foo are the same file
 alex:~ $ install foo bar ../../home/alex
 install: foo and ../../home/alex/foo are the same file
 alex:~ $ install foo bar /usr/home/alex 
 install: foo and /usr/home/alex/foo are the same file
 alex:~ $ install foo bar test/..       
 install: foo and test/../foo are the same file
 alex:~ $ 
 
 
 Here is the patch:
 
 --- xinstall.c.old	Wed Nov 17 20:32:40 1999
 +++ xinstall.c	Wed Nov 17 21:48:05 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. */
 @@ -105,6 +105,7 @@
  void	strip __P((char *));
  void	usage __P((void));
  int	trymmap __P((int));
 +char *	basename __P((char *));
  
  #define ALLOW_NUMERIC_IDS 1
  #ifdef ALLOW_NUMERIC_IDS
 @@ -128,7 +129,7 @@
  	int argc;
  	char *argv[];
  {
 -	struct stat from_sb, to_sb;
 +	struct stat from_sb, to_sb, fileto_sb;
  	mode_t *set;
  	u_long fset;
  	u_int iflags;
 @@ -222,8 +223,28 @@
  
  	no_target = stat(to_name = argv[argc - 1], &to_sb);
  	if (!no_target && (to_sb.st_mode & S_IFMT) == S_IFDIR) {
 -		for (; *argv != to_name; ++argv)
 -			install(*argv, to_name, fset, iflags | DIRECTORY);
 +		for (; *argv != to_name; ++argv) {
 +			if (stat(*argv, &from_sb))
 +				err(EX_OSERR, "%s", *argv);
 +			snprintf(pathbuf3, MAXPATHLEN,
 +			    "%s%s%s", to_name,
 +			    to_name[strlen(to_name) - 1] == '/' ? "" : "/",
 +			    basename(*argv));
 +			if (stat(pathbuf3, &fileto_sb) && errno != ENOENT)
 +				err(EX_OSERR, "%s", pathbuf3);
 +			else if (errno == ENOENT)
 +				goto target_ok;
 +			if (!S_ISREG(fileto_sb.st_mode)) {
 +				errno = EFTYPE;
 +				err(EX_OSERR, "%s", pathbuf3);
 +			}
 +			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", *argv, pathbuf3);
 +		target_ok:
 +			install(*argv, pathbuf3, fset, iflags);
 +	    }
  		exit(EX_OK);
  		/* NOTREACHED */
  	}
 @@ -736,4 +757,19 @@
  		return (1);
  #endif
  	return (0);
 +}
 +
 +/*
 + * basename --
 + *	return the filename of a file whose absolut path is given
 + *	as pointer to char.
 + */
 +char *
 +basename(name)
 +	char *name;
 +{
 +	char *slash;
 +
 +	slash = strrchr(name, '/');
 +	return (slash == NULL ? name : slash + 1);
  }
 


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?199911172100.NAA25431>