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 <[EMAIL PROTECTED]> * 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, ¤t_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, ¤t_stat); + assign_string (¤t_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, ¤t_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, ¤t_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. */ _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd