From owner-freebsd-bugs Wed Nov 17 13: 0: 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 31B3514D84 for ; Wed, 17 Nov 1999 13:00:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id NAA25431; Wed, 17 Nov 1999 13:00:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Date: Wed, 17 Nov 1999 13:00:02 -0800 (PST) Message-Id: <199911172100.NAA25431@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: 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