Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Allow hardlinks to symlinks.
details: https://anonhg.NetBSD.org/src/rev/3815c2918f20
branches: trunk
changeset: 476097:3815c2918f20
user: hubertf <hubertf%NetBSD.org@localhost>
date: Sun Sep 05 23:34:39 1999 +0000
description:
Allow hardlinks to symlinks.
Reviewed by: Bill Studenmund, Klaus Klein
diffstat:
bin/ln/ln.c | 6 ++--
gnu/usr.bin/cpio/copyin.c | 63 +++++++++++++++++++++++++++++++++++++++++++++
gnu/usr.bin/cpio/copyout.c | 39 +++++++++++++++++++++++++++-
gnu/usr.bin/cpio/copypass.c | 19 +++++++++++++
gnu/usr.bin/tar/create.c | 5 ++-
sys/kern/vfs_syscalls.c | 4 +-
6 files changed, 129 insertions(+), 7 deletions(-)
diffs (247 lines):
diff -r 93a735e6f7bc -r 3815c2918f20 bin/ln/ln.c
--- a/bin/ln/ln.c Sun Sep 05 21:22:38 1999 +0000
+++ b/bin/ln/ln.c Sun Sep 05 23:34:39 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ln.c,v 1.15 1998/07/28 05:31:25 mycroft Exp $ */
+/* $NetBSD: ln.c,v 1.16 1999/09/05 23:34:40 hubertf Exp $ */
/*
* Copyright (c) 1987, 1993, 1994
@@ -43,7 +43,7 @@
#if 0
static char sccsid[] = "@(#)ln.c 8.2 (Berkeley) 3/31/94";
#else
-__RCSID("$NetBSD: ln.c,v 1.15 1998/07/28 05:31:25 mycroft Exp $");
+__RCSID("$NetBSD: ln.c,v 1.16 1999/09/05 23:34:40 hubertf Exp $");
#endif
#endif /* not lint */
@@ -137,7 +137,7 @@
if (!sflag) {
/* If target doesn't exist, quit now. */
- if (stat(target, &sb)) {
+ if (lstat(target, &sb)) {
warn("%s", target);
return (1);
}
diff -r 93a735e6f7bc -r 3815c2918f20 gnu/usr.bin/cpio/copyin.c
--- a/gnu/usr.bin/cpio/copyin.c Sun Sep 05 21:22:38 1999 +0000
+++ b/gnu/usr.bin/cpio/copyin.c Sun Sep 05 23:34:39 1999 +0000
@@ -876,6 +876,68 @@
#ifdef CP_IFLNK
case CP_IFLNK:
{
+ /* Can the current symlink be linked to a previously copied
+ file? */
+ if (file_hdr.c_nlink > 1 && (archive_format == arf_newascii
+ || archive_format == arf_crcascii) )
+ {
+ int link_res;
+ if (file_hdr.c_filesize == 0)
+ {
+ /* See CP_IFREG case for how links are handled */
+ defer_copyin (&file_hdr);
+ toss_input (in_file_des, file_hdr.c_filesize);
+ skip_padding (in_file_des, file_hdr.c_filesize);
+ break;
+ }
+ /* If the file has data (filesize != 0), then presumably
+ any other links have already been defer_copyin'ed(),
+ but GNU cpio version 2.0-2.2 didn't do that, so we
+ still have to check for links here (and also in case
+ the archive was created and later appeneded to). */
+ link_res = link_to_maj_min_ino (file_hdr.c_name,
+ file_hdr.c_dev_maj, file_hdr.c_dev_maj,
+ file_hdr.c_ino);
+ if (link_res == 0)
+ {
+ toss_input (in_file_des, file_hdr.c_filesize);
+ skip_padding (in_file_des, file_hdr.c_filesize);
+ break;
+ }
+ }
+ else if (file_hdr.c_nlink > 1 && archive_format != arf_tar
+ && archive_format != arf_ustar)
+ {
+ int link_res;
+ link_res = link_to_maj_min_ino (file_hdr.c_name,
+ file_hdr.c_dev_maj, file_hdr.c_dev_maj,
+ file_hdr.c_ino);
+ if (link_res == 0)
+ {
+ toss_input (in_file_des, file_hdr.c_filesize);
+ skip_padding (in_file_des, file_hdr.c_filesize);
+ break;
+ }
+ }
+ else if ((archive_format == arf_tar || archive_format == arf_ustar)
+ && file_hdr.c_tar_linkname &&
+ file_hdr.c_tar_linkname[0] != '\0')
+ {
+ int link_res;
+ link_res = link_to_maj_min_ino (file_hdr.c_tar_linkname,
+ file_hdr.c_dev_maj, file_hdr.c_dev_maj,
+ file_hdr.c_ino);
+ if (link_res == 0)
+ {
+ toss_input (in_file_des, file_hdr.c_filesize);
+ skip_padding (in_file_des, file_hdr.c_filesize);
+ break;
+ }
+ }
+
+ /* If not linked, copy the contents of the file. */
+ if (link_name == NULL)
+ {
if (archive_format != arf_tar && archive_format != arf_ustar)
{
link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
@@ -911,6 +973,7 @@
error (0, errno, "%s", file_hdr.c_name);
free (link_name);
link_name = NULL;
+ }
}
break;
#endif
diff -r 93a735e6f7bc -r 3815c2918f20 gnu/usr.bin/cpio/copyout.c
--- a/gnu/usr.bin/cpio/copyout.c Sun Sep 05 21:22:38 1999 +0000
+++ b/gnu/usr.bin/cpio/copyout.c Sun Sep 05 23:34:39 1999 +0000
@@ -450,8 +450,9 @@
#ifdef CP_IFLNK
case CP_IFLNK:
{
- char *link_name = (char *) xmalloc (file_stat.st_size + 1);
+ char *link_name;
+ link_name = (char *) xmalloc (file_stat.st_size + 1);
if (readlink (input_name.ds_string, link_name,
file_stat.st_size) < 0)
{
@@ -459,6 +460,36 @@
free (link_name);
continue;
}
+
+#ifndef __MSDOS__
+ if (archive_format == arf_tar || archive_format == arf_ustar)
+ {
+ char *otherfile;
+ if ((otherfile = find_inode_file (file_hdr.c_ino,
+ file_hdr.c_dev_maj,
+ file_hdr.c_dev_min)))
+ {
+ file_hdr.c_mode = CP_IFREG; /* XXX hardlink! */
+ file_hdr.c_tar_linkname = otherfile;
+ write_out_header (&file_hdr, out_file_des);
+ break;
+ }
+ }
+ if ( (archive_format == arf_newascii || archive_format == arf_crcascii)
+ && (file_hdr.c_nlink > 1) )
+ {
+ if (last_link (&file_hdr) )
+ {
+ writeout_other_defers (&file_hdr, out_file_des);
+ }
+ else
+ {
+ add_link_defer (&file_hdr);
+ break;
+ }
+ }
+#endif
+
if (archive_format == arf_tar || archive_format == arf_ustar)
{
if (file_stat.st_size + 1 > 100)
@@ -479,6 +510,12 @@
copy_buf_out (link_name, out_file_des, file_stat.st_size);
pad_output (out_file_des, file_hdr.c_filesize);
}
+#ifndef __MSDOS__
+ if (archive_format == arf_tar || archive_format == arf_ustar)
+ add_inode (file_hdr.c_ino, input_name.ds_string, file_hdr.c_dev_maj,
+ file_hdr.c_dev_min);
+#endif
+
free (link_name);
}
break;
diff -r 93a735e6f7bc -r 3815c2918f20 gnu/usr.bin/cpio/copypass.c
--- a/gnu/usr.bin/cpio/copypass.c Sun Sep 05 21:22:38 1999 +0000
+++ b/gnu/usr.bin/cpio/copypass.c Sun Sep 05 23:34:39 1999 +0000
@@ -332,6 +332,24 @@
}
link_name[in_file_stat.st_size] = '\0';
+ /* Can the current symlink be linked to a another file?
+ Set link_name to the original file name. */
+ if (link_flag)
+ /* User said to link it if possible. Try and link to
+ the original copy. If that fails we'll still try
+ and link to a copy we've already made. */
+ link_res = link_to_name (output_name.ds_string,
+ input_name.ds_string);
+ if ( (link_res < 0) && (in_file_stat.st_nlink > 1) )
+ link_res = link_to_maj_min_ino (output_name.ds_string,
+ major (in_file_stat.st_dev),
+ minor (in_file_stat.st_dev),
+ in_file_stat.st_ino);
+
+ /* If the link was not (hard)linked, make a softlink. */
+ if (link_res < 0)
+ {
+
res = UMASKED_SYMLINK (link_name, output_name.ds_string,
in_file_stat.st_mode);
if (res < 0 && create_dir_flag)
@@ -355,6 +373,7 @@
&& errno != EPERM)
error (0, errno, "%s", output_name.ds_string);
free (link_name);
+ }
}
#endif
else
diff -r 93a735e6f7bc -r 3815c2918f20 gnu/usr.bin/tar/create.c
--- a/gnu/usr.bin/tar/create.c Sun Sep 05 21:22:38 1999 +0000
+++ b/gnu/usr.bin/tar/create.c Sun Sep 05 23:34:39 1999 +0000
@@ -18,7 +18,7 @@
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef lint
-static char rcsid[] = "$Id: create.c,v 1.7 1998/06/07 02:30:12 enami Exp $";
+static char rcsid[] = "$Id: create.c,v 1.8 1999/09/05 23:34:40 hubertf Exp $";
#endif /* not lint */
/*
@@ -293,6 +293,9 @@
#ifdef S_ISFIFO
|| S_ISFIFO (hstat.st_mode)
#endif
+#ifdef S_ISLNK
+ || S_ISLNK (hstat.st_mode)
+#endif
))
{
register struct link *lp;
diff -r 93a735e6f7bc -r 3815c2918f20 sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c Sun Sep 05 21:22:38 1999 +0000
+++ b/sys/kern/vfs_syscalls.c Sun Sep 05 23:34:39 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_syscalls.c,v 1.146 1999/07/31 03:18:43 christos Exp $ */
+/* $NetBSD: vfs_syscalls.c,v 1.147 1999/09/05 23:34:39 hubertf Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -1391,7 +1391,7 @@
struct nameidata nd;
int error;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
vp = nd.ni_vp;
Home |
Main Index |
Thread Index |
Old Index