diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2001-01-06 19:38:22 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2001-01-06 19:38:22 +0000 |
commit | 55ddb0165638d83827e406919e202c27f52e42b4 (patch) | |
tree | 2ba0f1f41c5b577c2b00c13fe16d2b0ff09bf434 /bin/mv/mv.c | |
parent | 3a58c1052ab36e5f3852e4aa216701876b3933b3 (diff) |
Fix 3 cases related to symbolic links when moving between filesystes:
1) incorrectly refused to move a symlink to a mount point
2) refused to move a symlink to a non-existent file
3) copied the contents of a symlink instead of the link itself.
Closes PR 1368; james@oaktree.co.uk
Diffstat (limited to 'bin/mv/mv.c')
-rw-r--r-- | bin/mv/mv.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/bin/mv/mv.c b/bin/mv/mv.c index 5d9acdf53c4..46f8a164ef1 100644 --- a/bin/mv/mv.c +++ b/bin/mv/mv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mv.c,v 1.15 1999/12/24 22:38:06 angelos Exp $ */ +/* $OpenBSD: mv.c,v 1.16 2001/01/06 19:38:21 millert Exp $ */ /* $NetBSD: mv.c,v 1.9 1995/03/21 09:06:52 cgd Exp $ */ /* @@ -47,7 +47,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)mv.c 8.2 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: mv.c,v 1.15 1999/12/24 22:38:06 angelos Exp $"; +static char rcsid[] = "$OpenBSD: mv.c,v 1.16 2001/01/06 19:38:21 millert Exp $"; #endif #endif /* not lint */ @@ -224,11 +224,21 @@ do_move(from, to) if (!rename(from, to)) return (0); - if (errno == EXDEV) { + if (errno != EXDEV) { + warn("rename %s to %s", from, to); + return (1); + } + + if (lstat(from, &sb)) { + warn("%s", from); + return (1); + } + + /* Disallow moving a mount point. */ + if (S_ISDIR(sb.st_mode)) { struct statfs sfs; char path[MAXPATHLEN]; - /* Can't mv(1) a mount point. */ if (realpath(from, path) == NULL) { warnx("cannot resolve %s: %s", from, path); return (1); @@ -237,9 +247,6 @@ do_move(from, to) warnx("cannot rename a mount point"); return (1); } - } else { - warn("rename %s to %s", from, to); - return (1); } /* @@ -248,7 +255,7 @@ do_move(from, to) * message to the standard error and do nothing more with the * current source file... */ - if (!stat(to, &sb)) { + if (!lstat(to, &sb)) { if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) { warn("can't remove %s", to); return (1); @@ -259,10 +266,6 @@ do_move(from, to) * (5) The file hierarchy rooted in source_file shall be duplicated * as a file hiearchy rooted in the destination path... */ - if (stat(from, &sb)) { - warn("%s", from); - return (1); - } return (S_ISREG(sb.st_mode) ? fastcopy(from, to, &sb) : copy(from, to)); } |