Date: Fri, 20 Apr 2001 17:38:52 +0300 From: Maxim Sobolev <sobomax@FreeBSD.org> To: audit@FreeBSD.org Cc: hackers@FreeBSD.org Subject: Merging ln(1) ``-h'' option from NetBSD [patch] Message-ID: <3AE049FC.60613D17@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------9D96218EA2955EAD73F8C911 Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Please somebody take a look at attached patch that adds ``-h'' option to the ln(1) command (obtained from NetBSD, which has it since 1997). In addition, I've tried to minimise diffs between our code and NetBSD's one, so there are several changes that at a first glance look superfluous. -Maxim --------------9D96218EA2955EAD73F8C911 Content-Type: text/plain; charset=koi8-r; name="ln.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ln.diff" Index: ln.1 =================================================================== RCS file: /home/ncvs/src/bin/ln/ln.1,v retrieving revision 1.14 diff -d -u -r1.14 ln.1 --- ln.1 2000/11/20 11:39:37 1.14 +++ ln.1 2001/04/20 14:36:37 @@ -44,11 +44,11 @@ .Nd make links .Sh SYNOPSIS .Nm -.Op Fl fisv +.Op Fl fhinsv .Ar source_file .Op target_file .Nm -.Op Fl fisv +.Op Fl fhinsv .Ar source_file ... .Op target_dir .Nm link @@ -79,6 +79,14 @@ option overrides any previous .Fl i options.) +.It Fl h +If the +.Ar target_file +or +.Ar target_dir +is a symbolic link, do not follow it. This is most useful with the +.Fl f +option, to replace a symlink which may point to a directory. .It Fl i Cause .Nm @@ -94,6 +102,12 @@ option overrides any previous .Fl f options.) +.It Fl n +Same as +.Fl h , +for compatibility with other +.Nm +implementations. .It Fl s Create a symbolic link. .It Fl v @@ -168,12 +182,18 @@ and .Fl v options are non-standard and their use in scripts is not recommended. -.Sh HISTORY -An +.Sh STANDARDS +The .Nm -command appeared in -.At v1 . +utility conforms to +.St -p1003.2-92 . +.Pp The simplified .Nm link command conforms to .St -susv2 . +.Sh HISTORY +An +.Nm +command appeared in +.At v1 . Index: ln.c =================================================================== RCS file: /home/ncvs/src/bin/ln/ln.c,v retrieving revision 1.18 diff -d -u -r1.18 ln.c --- ln.c 2000/08/17 16:08:06 1.18 +++ ln.c 2001/04/20 14:36:37 @@ -57,6 +57,7 @@ int fflag; /* Unlink existing files. */ int iflag; /* Interactive mode. */ +int hflag; /* Check new name for symlink first. */ int sflag; /* Symbolic, not hard, link. */ int vflag; /* Verbose output. */ /* System link call. */ @@ -65,6 +66,7 @@ int linkit __P((char *, char *, int)); void usage __P((void)); +int main __P((int, char *[])); int main(argc, argv) @@ -73,7 +75,8 @@ { struct stat sb; int ch, exitval; - char *p, *sourcedir; + char *p; + char *sourcedir; /* * Test for the special case where the utility is called as @@ -92,12 +95,16 @@ usage(); } - while ((ch = getopt(argc, argv, "fisv")) != -1) + while ((ch = getopt(argc, argv, "fhinsv")) != -1) switch (ch) { case 'f': fflag = 1; iflag = 0; break; + case 'h': + case 'n': + hflag = 1; + break; case 'i': iflag = 1; fflag = 0; @@ -122,13 +129,22 @@ switch(argc) { case 0: usage(); + /* NOTREACHED */ case 1: /* ln target */ exit(linkit(argv[0], ".", 1)); + /* NOTREACHED */ case 2: /* ln target source */ exit(linkit(argv[0], argv[1], 0)); + /* NOTREACHED */ } /* ln target1 target2 directory */ sourcedir = argv[argc - 1]; + if (hflag && lstat(sourcedir, &sb) == 0 && S_ISLNK(sb.st_mode)) { + /* we were asked not to follow symlinks, but found one at + the target--simulate "not a directory" error */ + errno = ENOTDIR; + err(1, "%s", sourcedir); + } if (stat(sourcedir, &sb)) err(1, "%s", sourcedir); if (!S_ISDIR(sb.st_mode)) @@ -136,6 +152,7 @@ for (exitval = 0; *argv != sourcedir; ++argv) exitval |= linkit(*argv, sourcedir, 1); exit(exitval); + /* NOTREACHED */ } int @@ -161,18 +178,20 @@ } } - /* If the source is a directory, append the target's name. */ - if (isdir || ((exists = !stat(source, &sb)) && S_ISDIR(sb.st_mode))) { + /* If the source is a directory (and not a symlink if hflag), + append the target's name. */ + if (isdir || + (!lstat(source, &sb) && S_ISDIR(sb.st_mode)) || + (!hflag && !stat(source, &sb) && S_ISDIR(sb.st_mode))) { if ((p = strrchr(target, '/')) == NULL) p = target; else ++p; (void)snprintf(path, sizeof(path), "%s/%s", source, p); source = path; - exists = !lstat(source, &sb); - } else - exists = !lstat(source, &sb); + } + exists = !lstat(source, &sb); /* * If the file exists, then unlink it forcibly if -f was specified * and interactively if -i was specified. @@ -214,8 +233,9 @@ usage() { (void)fprintf(stderr, "%s\n%s\n%s\n", - "usage: ln [-fisv] file1 file2", - " ln [-fisv] file ... directory", + "usage: ln [-fhinsv] file1 file2", + " ln [-fhinsv] file ... directory", " link file1 file2"); exit(1); + /* NOTREACHED */ } --------------9D96218EA2955EAD73F8C911-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3AE049FC.60613D17>