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