bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Translator support for GNU tar


From: Marco Gerards
Subject: Translator support for GNU tar
Date: 19 Jun 2003 22:22:34 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Hi,

I wrote a patch for GNU tar to support passive translators. Can
someone please check it (especially the Hurd part) before I send it to
the tar mailinglist?

My biggest problem is autoconf. It doesn't even work perfectly for the
orginal sourcecode. I've added a test to check for the Hurd by looking
for hurd.h, is that correct?

To add translators to a tar file you have to use the "-a" switch. It
doesn't add symlinks, devices and fifos. I guess that is the behaviour
we want. I haven't added any code to support stacking of translators
or reading the underlaying filecontent (I saw something about this in
the bug-hurd archives, but it sounds like non-sense to me ;)).

I have a question about the output while verbosely listing the tarball
content. Now I use a format like: ">> /hurd/ext2fs /dev/hd0s2" just
like the output for symlinks, but ">>" instead of "->". Is this the
output we want? Alfred, what did you use for ls?

I really appreciate any feedback, even about the changelog (My english
sucks and I guess I made some mistakes). :)

Thanks,
Marco

ps. this code wants to be tested ;)

2003-06-19  Marco Gerards  <metgerards@student.han.nl>

        * configure.ac: Check for hurd.h.
        * src/common.h (dump_translator_option): New variable.
        (trans_stat): New prototype.
        * compare.c: Include hurd.h when compiling for the Hurd.
        (diff_archive): Compare GNUTYPE_TRANS when compiling for the
        Hurd.
        * create.c: Include hurd.h and argz.h when compiling for the Hurd.
        (write_long): Mention GNUTYPE_LONGTRANS in comment.
        (finish_header): Check for GNUTYPE_LONGTRANS.
        (dump_file): Dump translators when the translator when
        appropiate.
        * extract.c:  Include hurd.h and argz.h when compiling for the
        Hurd.
        (extract_archive): Check for GNUTYPE_LONGTRANS and handle it
        like GNUTYPE_LONGNAME and GNUTYPE_LONGLINK.
        (extract_archive): Make GNUTYPE_TRANS extract passive translators.
        * list.c (read_header): Handle GNUTYPE_LONGTRANS.
        print_header (GNUTYPE_TRANS): Show filemode as 'T'. List the
        translator as a space seperated string (showtrans like
        output).
        * misc.c:  Include hurd.h when compiling for the Hurd.
        (trans_stat): New function.
        (gettrans_error): Likewise.
        (gettrans_warn): Likewise.
        (settrans_error): Likewise.
        * tar.c (long_options): Added no-deref-trans as option to dump
        passive translators. (only available for the Hurd).
        (usage): add documentation for no-deref-trans. (only available for the 
Hurd).
        (OPTION_STRING): Add 'a' as short option for
        no-deref-trans. (only available for the Hurd).
        (decode_options): Parse 'a' parameter. (only available for the
        Hurd).
        * tar.h (GNUTYPE_TRANS): New macro.
        (GNUTYPE_LONGTRANS): Likewise.
        
        
diff -upr tar-1.13.25/configure.ac tar-1.13.25_hurd/configure.ac
--- tar-1.13.25/configure.ac    2001-09-26 22:30:53.000000000 +0200
+++ tar-1.13.25_hurd/configure.ac       2003-06-19 19:27:30.000000000 +0200
@@ -47,7 +47,7 @@ AC_CHECK_HEADERS(fcntl.h limits.h linux/
   sys/buf.h sys/device.h sys/gentape.h \
   sys/inet.h sys/io/trioctl.h sys/ioccom.h \
   sys/mtio.h sys/param.h sys/tprintf.h sys/tape.h sys/time.h sys/timeb.h \
-  unistd.h wchar.h wctype.h)
+  unistd.h wchar.h wctype.h hurd.h)
 
 AC_HEADER_SYS_WAIT
 
diff -upr tar-1.13.25/src/common.h tar-1.13.25_hurd/src/common.h
--- tar-1.13.25/src/common.h    2001-09-21 02:00:55.000000000 +0200
+++ tar-1.13.25_hurd/src/common.h       2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* Common declarations for the tar program.
 
-   Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001 Free
-   Software Foundation, Inc.
+   Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
+   2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
@@ -149,6 +149,9 @@ GLOBAL const char *use_compress_program_
 /* Boolean value.  */
 GLOBAL int dereference_option;
 
+/* Boolean value.  */
+GLOBAL int dump_translators_option;
+
 /* Patterns that match file names to be excluded.  */
 GLOBAL struct exclude *excluded;
 
@@ -483,6 +486,7 @@ int remove_any_file PARAMS ((const char 
 int maybe_backup_file PARAMS ((const char *, int));
 void undo_last_backup PARAMS ((void));
 
+int trans_stat PARAMS ((char const *, struct stat *));
 int deref_stat PARAMS ((int, char const *, struct stat *));
 
 int chdir_arg PARAMS ((char const *));
diff -upr tar-1.13.25/src/compare.c tar-1.13.25_hurd/src/compare.c
--- tar-1.13.25/src/compare.c   2001-09-22 02:47:09.000000000 +0200
+++ tar-1.13.25_hurd/src/compare.c      2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* Diff files from a tar archive.
 
-   Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001 Free
-   Software Foundation, Inc.
+   Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
+   2003 Free Software Foundation, Inc.
 
    Written by John Gilmore, on 1987-04-30.
 
@@ -37,6 +37,10 @@ struct utimbuf
 
 #include <quotearg.h>
 
+#if HAVE_HURD_H
+# include <hurd.h>
+#endif
+
 #include "common.h"
 #include "rmt.h"
 
@@ -734,6 +738,55 @@ diff_archive (void)
 
        break;
       }
+
+#if HAVE_HURD_H
+    case GNUTYPE_TRANS:
+      {
+       size_t len = strlen (current_link_name);
+       size_t translen = len;
+       char *buf = alloca (len + 1);
+       char *transbuf = buf;
+
+       file_t node;
+
+       node = file_name_lookup (current_file_name, O_NOTRANS, 0);
+       if (node == MACH_PORT_NULL)
+         {
+           gettrans_warn (current_file_name);
+           report_difference (0);
+           skip_member ();
+           break;
+         }    
+
+       status = file_get_translator (node, &transbuf, &translen);
+       if (status == EINVAL)
+         {
+           mach_port_deallocate (mach_task_self (), node);
+           gettrans_warn (current_file_name);
+           report_difference (0);
+           skip_member ();
+           break;
+         }
+
+       if (status)
+         {
+           mach_port_deallocate (mach_task_self (), node);
+           gettrans_error (current_file_name);
+           report_difference (0);
+           break;
+         }
+       else if (len != translen
+                || strncmp (current_link_name, transbuf, len) != 0)
+         report_difference (_("Translator differs"));
+
+       if (transbuf != buf)
+         munmap (transbuf, translen);
+
+       mach_port_deallocate (mach_task_self (), node);
+       
+       break;
+      }
+#endif
     }
 }
 
diff -upr tar-1.13.25/src/create.c tar-1.13.25_hurd/src/create.c
--- tar-1.13.25/src/create.c    2001-08-29 23:21:02.000000000 +0200
+++ tar-1.13.25_hurd/src/create.c       2003-06-19 19:27:32.000000000 +0200
@@ -1,5 +1,7 @@
 /* Create a tar archive.
-   Copyright 1985,92,93,94,96,97,99,2000, 2001 Free Software Foundation, Inc.
+   Copyright 1985,92,93,94,96,97,99,2000, 2001, 2003
+   Free Software Foundation, Inc.
+
    Written by John Gilmore, on 1985-08-25.
 
    This program is free software; you can redistribute it and/or modify it
@@ -38,6 +40,11 @@ struct utimbuf
 #include "common.h"
 #include <hash.h>
 
+#if HAVE_HURD_H
+# include <hurd.h>
+# include <argz.h>
+#endif
+
 #ifndef MSDOS
 extern dev_t ar_dev;
 extern ino_t ar_ino;
@@ -351,7 +358,8 @@ write_eot (void)
   set_next_block_after (pointer);
 }
 
-/* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block.  */
+/* Write a GNUTYPE_LONGLINK, GNUTYPE_LONGNAME or GNUTYPE_LONGTRANS
+   block.  */
 
 /* FIXME: Cross recursion between start_header and write_long!  */
 
@@ -568,7 +576,8 @@ finish_header (union block *header)
 
   if (verbose_option
       && header->header.typeflag != GNUTYPE_LONGLINK
-      && header->header.typeflag != GNUTYPE_LONGNAME)
+      && header->header.typeflag != GNUTYPE_LONGNAME
+      && header->header.typeflag != GNUTYPE_LONGTRANS)
     {
       /* These globals are parameters to print_header, sigh.  */
 
@@ -902,6 +911,7 @@ dump_file (char *p, int top_level, dev_t
   char save_typeflag;
   time_t original_ctime;
   struct utimbuf restore_times;
+  int status;
 
   /* FIXME: `header' might be used uninitialized in this
      function.  Reported by Bruno Haible.  */
@@ -909,6 +919,80 @@ dump_file (char *p, int top_level, dev_t
   if (interactive_option && !confirm ("add", p))
     return;
 
+#if HAVE_HURD_H
+  /* Set a translator. There is a better way to descibe the translator
+     (symlink for example) this translator will be overwritten.  */
+  if (dump_translators_option)
+    {
+      file_t node;
+      char buf[1024];
+      char *transbuf = buf;
+      size_t translen = sizeof (buf);
+      
+      node = file_name_lookup (p, O_NOTRANS, 0);
+      if (node == MACH_PORT_NULL)
+       {
+         open_error (p);
+         return;
+       }
+      else
+       {
+         if (trans_stat (p, &current_stat) != 0)
+           {
+             mach_port_deallocate (mach_task_self (), node);
+             
+             if (ignore_failed_read_option)
+               stat_warn (p);
+             else
+               stat_error (p);
+             
+             return;
+           }
+         
+         /* Check if the node is a translator of a type that should be
+            stored.  */
+         if (S_ISLNK (current_stat.st_mode) || 
+             S_ISFIFO (current_stat.st_mode) ||
+             S_ISCHR (current_stat.st_mode) || 
+             S_ISBLK (current_stat.st_mode))
+           mach_port_deallocate (mach_task_self (), node);
+         else
+           {
+             status = file_get_translator (node, &transbuf, &translen);
+             
+             mach_port_deallocate (mach_task_self (), node);
+             
+             if (status && status != EINVAL)
+               {
+                 /* FIXME: Should EINVAL be handled in some way?  */
+                 gettrans_error (p);
+                 return;
+               }
+             else if (status != EINVAL)
+               {
+                 /* FIXME: The translator is stored in a argz
+                    list. These lists have parameters seperated by
+                    0's. Replace the 0's by 1's so it can se stored
+                    by tar.  */
+                 argz_stringify (transbuf, translen, 1);
+                 
+                 if (NAME_FIELD_SIZE <= translen)
+                   write_long (transbuf, GNUTYPE_LONGTRANS);
+                 
+                 header = start_header (p, &current_stat);
+                 assign_string (&current_link_name, transbuf);
+                 strncpy (header->header.linkname, transbuf, NAME_FIELD_SIZE);
+                 header->header.linkname[NAME_FIELD_SIZE - 1] = '\0';
+                 header->header.typeflag = GNUTYPE_TRANS;
+                 finish_header (header);
+                 
+                 return;
+               }
+           }
+       }
+    }
+#endif
+  
   if (deref_stat (dereference_option, p, &current_stat) != 0)
     {
       if (ignore_failed_read_option)
@@ -917,7 +1001,7 @@ dump_file (char *p, int top_level, dev_t
        stat_error (p);
       return;
     }
-
+  
   original_ctime = current_stat.st_ctime;
   restore_times.actime = current_stat.st_atime;
   restore_times.modtime = current_stat.st_mtime;
diff -upr tar-1.13.25/src/extract.c tar-1.13.25_hurd/src/extract.c
--- tar-1.13.25/src/extract.c   2001-09-24 20:55:17.000000000 +0200
+++ tar-1.13.25_hurd/src/extract.c      2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* Extract files from a tar archive.
 
    Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
-   2001 Free Software Foundation, Inc.
+   2001, 2003 Free Software Foundation, Inc.
 
    Written by John Gilmore, on 1985-11-19.
 
@@ -22,6 +22,11 @@
 #include "system.h"
 #include <quotearg.h>
 
+#if HAVE_HURD_H
+# include <hurd.h>
+# include <argz.h>
+#endif
+
 #if HAVE_UTIME_H
 # include <utime.h>
 #else
@@ -1213,12 +1218,51 @@ extract_archive (void)
 
     case GNUTYPE_LONGNAME:
     case GNUTYPE_LONGLINK:
+    case GNUTYPE_LONGTRANS:
       ERROR ((0, 0, _("Visible long name error")));
       skip_member ();
       if (backup_option)
        undo_last_backup ();
       break;
 
+#if HAVE_HURD_H
+    case GNUTYPE_TRANS:
+      {
+       file_t node;
+       char *argz = 0;
+       size_t argz_len = 0;
+
+       if (!prepare_to_extract (CURRENT_FILE_NAME))
+         break;
+
+       node = file_name_lookup (CURRENT_FILE_NAME, O_NOTRANS | O_CREAT, 
+                                600);
+
+       if (node == MACH_PORT_NULL)
+         {
+           open_error (CURRENT_FILE_NAME);
+           break;
+         }
+
+       set_stat (CURRENT_FILE_NAME, &current_stat, 0, 0,
+                 ARCHIVED_PERMSTATUS, typeflag);
+
+       argz_create_sep (current_link_name, 1, &argz, &argz_len);
+
+       status = file_set_translator (node, 
+                                     FS_TRANS_SET | FS_TRANS_EXCL,
+                                     FS_TRANS_SET | FS_TRANS_EXCL, 0,
+                                     argz, argz_len,
+                                     MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+       
+       if (status)
+         settrans_error (CURRENT_FILE_NAME);
+
+       mach_port_deallocate (mach_task_self (), node);
+       break;
+      }
+#endif
+
     default:
       WARN ((0, 0,
             _("%s: Unknown file type '%c', extracted as normal file"),
diff -upr tar-1.13.25/src/list.c tar-1.13.25_hurd/src/list.c
--- tar-1.13.25/src/list.c      2001-09-26 22:05:04.000000000 +0200
+++ tar-1.13.25_hurd/src/list.c 2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* List a tar archive, with support routines for reading a tar archive.
 
    Copyright 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
-   2001 Free Software Foundation, Inc.
+   2001, 2003 Free Software Foundation, Inc.
 
    Written by John Gilmore, on 1985-08-26.
 
@@ -326,7 +326,8 @@ read_header (bool raw_extended_headers)
        current_stat.st_size = OFF_FROM_HEADER (header->header.size);
 
       if (header->header.typeflag == GNUTYPE_LONGNAME
-         || header->header.typeflag == GNUTYPE_LONGLINK)
+         || header->header.typeflag == GNUTYPE_LONGLINK
+         || header->header.typeflag == GNUTYPE_LONGTRANS)
        {
          if (raw_extended_headers)
            return HEADER_SUCCESS_EXTENDED;
@@ -941,6 +942,10 @@ print_header (void)
          modes[0] = 'N';
          break;
 
+       case GNUTYPE_TRANS:
+         modes[0] = 'T';
+         break;
+
        case GNUTYPE_LONGNAME:
        case GNUTYPE_LONGLINK:
          ERROR ((0, 0, _("Visible longname error")));
@@ -1074,6 +1079,22 @@ print_header (void)
          fprintf (stdlis, _(" link to %s\n"), quotearg (current_link_name));
          break;
 
+       case GNUTYPE_TRANS:
+         {
+           char *s = current_link_name;
+
+           /* Use the seperator ' ' instead of 1 to print the string.  */
+           while (*s)
+             {
+               if (*s == 1)
+                 *s = ' ';
+               s++;
+             }
+
+           fprintf (stdlis, " >> %s\n", quotearg (current_link_name));
+           break;
+         }
+
        default:
          {
            char type_string[2];
diff -upr tar-1.13.25/src/misc.c tar-1.13.25_hurd/src/misc.c
--- tar-1.13.25/src/misc.c      2001-08-27 01:14:26.000000000 +0200
+++ tar-1.13.25_hurd/src/misc.c 2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* Miscellaneous functions, not really specific to GNU tar.
 
-   Copyright 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001 Free
-   Software Foundation, Inc.
+   Copyright 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
+   2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
@@ -23,6 +23,10 @@
 #include <quotearg.h>
 #include <save-cwd.h>
 
+#if HAVE_HURD_H
+# include <hurd.h>
+#endif
+
 static void call_arg_fatal PARAMS ((char const *, char const *))
      __attribute__ ((noreturn));
 
@@ -395,6 +399,34 @@ undo_last_backup (void)
     }
 }
 
+#if HAVE_HURD_H
+/* Stat the underlaying node of node NAME. Save the stat information
+   in BUF.  */
+int
+trans_stat (char const *name, struct stat *buf)
+{
+  file_t node;
+  error_t err;
+
+  node = file_name_lookup (name, O_NOTRANS, 0);
+  if (!node)
+    {
+      mach_port_deallocate (mach_task_self (), node);
+      return ENOENT;
+    }
+
+  err = io_stat (node, buf);
+  
+  if (err)
+    {
+      mach_port_deallocate (mach_task_self (), node);
+      return err;
+    }
+
+  return 0;
+}
+#endif
+
 /* Depending on DEREF, apply either stat or lstat to (NAME, BUF).  */
 int
 deref_stat (int deref, char const *name, struct stat *buf)
@@ -688,6 +720,26 @@ readlink_warn (char const *name)
   call_arg_warn ("readlink", name);
 }
 
+#if HAVE_HURD_H
+void
+gettrans_error (char const *name)
+{
+  call_arg_error ("gettrans", name);
+}
+
+void
+gettrans_warn (char const *name)
+{
+  call_arg_warn ("gettrans", name);
+}
+
+void
+settrans_error (char const *name)
+{
+  call_arg_error ("gettrans", name);
+}
+#endif
+
 void
 savedir_error (char const *name)
 {
diff -upr tar-1.13.25/src/tar.c tar-1.13.25_hurd/src/tar.c
--- tar-1.13.25/src/tar.c       2001-09-21 02:11:27.000000000 +0200
+++ tar-1.13.25_hurd/src/tar.c  2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* A tar (tape archiver) program.
 
-   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
+   2001, 2003 Free Software Foundation, Inc.
 
    Written by John Gilmore, starting 1985-08-25.
 
@@ -227,6 +227,9 @@ static struct option long_options[] =
   {"newer-mtime", required_argument, 0, NEWER_MTIME_OPTION},
   {"null", no_argument, 0, NULL_OPTION},
   {"no-anchored", no_argument, 0, NO_ANCHORED_OPTION},
+#if HAVE_HURD_H
+  {"no-deref-trans", no_argument, 0, 'a'},
+#endif
   {"no-ignore-case", no_argument, 0, NO_IGNORE_CASE_OPTION},
   {"no-wildcards", no_argument, 0, NO_WILDCARDS_OPTION},
   {"no-wildcards-match-slash", no_argument, 0, 
NO_WILDCARDS_MATCH_SLASH_OPTION},
@@ -388,7 +391,12 @@ Archive format selection:\n\
             stdout);
       fputs (_("\
 \n\
-Local file selection:\n\
+Local file selection:\n"), stdout);
+#if HAVE_HURD_H
+      fputs (_("\
+  -a  --no-deref-trans         dump the translator\n"), stdout);
+#endif
+      fputs (_("\
   -C, --directory=DIR          change to directory DIR\n\
   -T, --files-from=NAME        get names to extract or create from file NAME\n\
       --null                   -T reads null-terminated names, disable -C\n\
@@ -456,7 +464,7 @@ or a file name starting with `/' or `.',
 
 /* Parse the options for tar.  */
 
-/* Available option letters are DEHIJQY and aenqy.  Some are reserved:
+/* Available option letters are DEHIJQY and enqy.  Some are reserved:
 
    e  exit immediately with a nonzero exit status if unexpected errors occur
    E  use extended headers (draft POSIX headers, that is)
@@ -467,7 +475,7 @@ or a file name starting with `/' or `.',
    Y  per-block gzip compression */
 
 #define OPTION_STRING \
-  "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zb:cdf:g:hijklmoprstuvwxyz"
+  "-01234567ABC:F:GIK:L:MN:OPRST:UV:WX:Zab:cdf:g:hijklmoprstuvwxyz"
 
 static void
 set_subcommand_option (enum subcommand subcommand)
@@ -592,6 +600,13 @@ decode_options (int argc, char **argv)
        input_files++;
        break;
 
+#if HAVE_HURD_H
+      case 'a':
+       /* Dump translators.  */
+       dump_translators_option = 1;
+       break;
+#endif
+
       case 'A':
        set_subcommand_option (CAT_SUBCOMMAND);
        break;
diff -upr tar-1.13.25/src/tar.h tar-1.13.25_hurd/src/tar.h
--- tar-1.13.25/src/tar.h       2001-09-21 06:23:01.000000000 +0200
+++ tar-1.13.25_hurd/src/tar.h  2003-06-19 19:27:32.000000000 +0200
@@ -1,7 +1,7 @@
 /* GNU tar Archive Format description.
 
    Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 2000, 2001 Free Software Foundation, Inc.
+   1997, 2000, 2001, 2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
@@ -209,6 +209,12 @@ struct oldgnu_header
 /* This file is a tape/volume header.  Ignore it on extraction.  */
 #define GNUTYPE_VOLHDR 'V'
 
+/* Store Hurd translators.  */
+#define GNUTYPE_TRANS 'T'
+
+/* Identifies the *next* file on the tape as having a long translatorname.  */
+#define GNUTYPE_LONGTRANS 'A'
+
 /* tar Header Block, overall structure.  */
 
 /* tar files are made in basic blocks of this size.  */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]