diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2001-08-09 00:03:13 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2001-08-09 00:03:13 +0000 |
commit | cd7ff4d11cc513cd3bf9cc03ae43734fae3e4421 (patch) | |
tree | 8dac2fe0ddb52317cd89dd323205b592494b9be3 | |
parent | 04583b13c583bba9f63564b3473f69d9b76bbb7f (diff) |
Add -h flag to prevent following a symlink to a dir as the dest.
Also add -n as an alias for -h for compat with GNU ln.
Patch from Phil.Pennock@globnix.org with minor changes by me.
-rw-r--r-- | bin/ln/ln.1 | 30 | ||||
-rw-r--r-- | bin/ln/ln.c | 22 |
2 files changed, 44 insertions, 8 deletions
diff --git a/bin/ln/ln.1 b/bin/ln/ln.1 index b111ebba87a..8d4510b5002 100644 --- a/bin/ln/ln.1 +++ b/bin/ln/ln.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ln.1,v 1.10 2000/11/09 17:51:55 aaron Exp $ +.\" $OpenBSD: ln.1,v 1.11 2001/08/09 00:03:12 millert Exp $ .\" $NetBSD: ln.1,v 1.10 1995/07/25 19:37:04 jtc Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 @@ -45,7 +45,7 @@ .Nd make hard and symbolic links to files .Sh SYNOPSIS .Nm ln -.Op Fl fs +.Op Fl fhns .Ar source_file .Op Ar target_file .Nm ln @@ -70,6 +70,12 @@ The options are as follows: .Bl -tag -width Ds .It Fl f Unlink any already existing file, permitting the link to occur. +.It Fl h +If the target is a symlink to a directory, do not descend into it. +.It Fl n +An alias for +.Fn h +for compatibility with other operating systems. .It Fl s Create a symbolic link. .El @@ -152,6 +158,26 @@ This hard link exists so may be invoked from shell scripts, for example, using the .Cm "if [ ]" construct. +.Pp +.Cm "mkdir bar baz; ln -s bar foo; ln -shf baz foo" +.Pp +The second call to +.Nm +removes the original +.Pa foo +and creates a replacement pointing to +.Pa baz . +Without the +.Ar -h +option, this would instead leave +.Pa foo +pointing to +.Pa bar +and inside +.Pa foo +create a new symlink +.Pa baz +pointing to itself. This results from directory-walking. .Sh SEE ALSO .Xr link 2 , .Xr lstat 2 , diff --git a/bin/ln/ln.c b/bin/ln/ln.c index 294d9382e5d..715eede32a6 100644 --- a/bin/ln/ln.c +++ b/bin/ln/ln.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ln.c,v 1.4 1996/12/14 12:18:01 mickey Exp $ */ +/* $OpenBSD: ln.c,v 1.5 2001/08/09 00:03:12 millert Exp $ */ /* $NetBSD: ln.c,v 1.10 1995/03/21 09:06:10 cgd Exp $ */ /* @@ -35,16 +35,16 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1987, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 -static char sccsid[] = "@(#)ln.c 8.2 (Berkeley) 3/31/94"; +static const char sccsid[] = "@(#)ln.c 8.2 (Berkeley) 3/31/94"; #else -static char rcsid[] = "$OpenBSD: ln.c,v 1.4 1996/12/14 12:18:01 mickey Exp $"; +static const char rcsid[] = "$OpenBSD: ln.c,v 1.5 2001/08/09 00:03:12 millert Exp $"; #endif #endif /* not lint */ @@ -60,6 +60,7 @@ static char rcsid[] = "$OpenBSD: ln.c,v 1.4 1996/12/14 12:18:01 mickey Exp $"; int dirflag; /* Undocumented directory flag. */ int fflag; /* Unlink existing files. */ +int hflag; /* Check new name for symlink first. */ int sflag; /* Symbolic, not hard, link. */ /* System link call. */ int (*linkf) __P((const char *, const char *)); @@ -76,7 +77,7 @@ main(argc, argv) int ch, exitval; char *sourcedir; - while ((ch = getopt(argc, argv, "Ffs")) != -1) + while ((ch = getopt(argc, argv, "Ffhns")) != -1) switch (ch) { case 'F': dirflag = 1; /* XXX: deliberately undocumented. */ @@ -84,6 +85,10 @@ main(argc, argv) case 'f': fflag = 1; break; + case 'h': + case 'n': + hflag = 1; + break; case 's': sflag = 1; break; @@ -122,6 +127,7 @@ linkit(target, source, isdir) { struct stat sb; char *p, path[MAXPATHLEN]; + int (*statf) __P((const char *, struct stat *)); if (!sflag) { /* If target doesn't exist, quit now. */ @@ -136,6 +142,8 @@ linkit(target, source, isdir) } } + statf = hflag ? lstat : stat; + /* If the source is a directory, append the target's name. */ if (isdir || (!stat(source, &sb) && S_ISDIR(sb.st_mode))) { if ((p = strrchr(target, '/')) == NULL) @@ -162,8 +170,10 @@ linkit(target, source, isdir) void usage() { + extern char *__progname; (void)fprintf(stderr, - "usage:\tln [-fs] file1 file2\n\tln [-fs] file ... directory\n"); + "usage: %s [-fhns] file1 file2\n\tln [-fhns] file ... directory\n", + __progname); exit(1); } |