diff -ru tar-1.13/src/buffer.c tar-1.13.1/src/buffer.c
--- tar-1.13/src/buffer.c	Mon Jul  5 08:47:59 1999
+++ tar-1.13.1/src/buffer.c	Sun Aug  6 23:37:01 2000
@@ -68,6 +68,7 @@
 /* Where we write list messages (not errors, not interactions) to.  Stdout
    unless we're writing a pipe, in which case stderr.  */
 FILE *stdlis;
+FILE *stdrec;
 
 static void backspace_output PARAMS ((void));
 static int new_volume PARAMS ((enum access_mode));
@@ -83,6 +84,9 @@
 /* PID of child program, if compress_option or remote archive access.  */
 static pid_t child_pid;
 
+/* Record number of the start of this block of records  */
+long baserec = 0 ;
+
 /* Error recovery stuff  */
 static int read_error_count;
 
@@ -144,9 +148,11 @@
 
 #endif /* DEBUG FORK */
 
+time_t start_time ;
 void
 init_total_written (void)
 {
+  start_time = time(0);
   clear_tarlong (total_written);
   clear_tarlong (bytes_written);
 }
@@ -154,8 +160,12 @@
 void
 print_total_written (void)
 {
+  time_t end_time = time(0);
   fprintf (stderr, _("Total bytes written: "));
   print_tarlong (total_written, stderr);
+  fprintf (stderr, _(" ("));
+  print_tarlong ((total_written/(end_time-start_time))>>10, stderr);
+  fprintf (stderr,"KB per second)");
   fprintf (stderr, "\n");
 }
 
@@ -680,8 +690,48 @@
 open_archive (enum access_mode access)
 {
   int backed_up_flag = 0;
+  time_t start_time = time(0) ;
 
-  stdlis = to_stdout_option ? stderr : stdout;
+  stdrec = stdlis = to_stdout_option ? stderr : stdout;
+
+  if ( record_file_name != NULL )
+    {
+#define INSERT_TIMESTAMP
+#ifdef INSERT_TIMESTAMP
+      /*
+       * A record-file name with '%T' will be expanded with a decimal
+       * value for the timestamp of the archive. This is the time value
+       * stored in the label record.
+       * If you are using only one computer, this should be a unique number.
+       * You are able to create different rec-files for all your archives,
+       * as well as finding the index of your archive in a reliable way.
+       *
+       * Another way would be to let us set the timestamp by another option.
+       * tar --timestamp <ts-number> ...
+       */
+      char rfn[256];
+      if ( access == ACCESS_READ ) {
+        char*p= record_file_name ;
+        int i = 0 ;
+        int n;
+        while ( p[0] != '\0' ) {
+          if ( p[0] == '%' && p[1] == 'T' ) {
+            /* i += */ sprintf(rfn+i,"%d",start_time);
+            i = strlen(rfn) ;
+            p += 2 ;
+          } else { rfn[i++] = *p++ ; }
+        }
+        rfn[i] = '\0' ;
+      } else strcpy(rfn,record_file_name);
+#else
+      char*rfn=record_file_name;
+#endif
+      if ( ( stdrec = fopen(rfn,"w")) == NULL )
+        {
+          fprintf(stdlis,"Cannot open %s.\n",record_file_name);
+          exit(1);
+        }
+    }
 
   if (record_size == 0)
     FATAL_ERROR ((0, 0, _("Invalid value for record_size")));
@@ -841,6 +891,46 @@
   setmode (archive, O_BINARY);
 #endif
 
+#if defined(MTIOCGET)
+  /* Prints the file number of the archive */
+  if ( block_number_option )
+    {
+      struct mtget get ;
+      int i ;
+      i = ioctl(archive,MTIOCGET,&get);
+      if (( i == 0 ) && ( get.mt_fileno >= 0 ))
+        {
+          fprintf(stdrec,
+            "loc             number of the file is %d \n",
+            get.mt_fileno );
+        }
+    }
+#endif
+
+#if defined(MTIOCPOS)
+  /* Prints the tape block number on every Linux SCSI-device */
+  if ( block_number_option )
+    {
+      struct mtpos pos ;
+      int i ;
+      i = ioctl(archive,MTIOCPOS,&pos);
+      if ( i == 0 )
+        {
+          fprintf(stdrec,
+            "loc             number of the first block is %d\n",
+            pos.mt_blkno );
+        }
+    }
+#endif
+
+  /* Prints the size of the blocks */
+  if ( block_number_option && blocking_factor != 20 )
+    {
+      fprintf(stdrec,
+        "loc             block length is %d bytes = %d * 512 bytes\n",
+	blocking_factor*512,blocking_factor);
+    }
+
   switch (access)
     {
     case ACCESS_READ:
@@ -874,7 +964,7 @@
 	  assign_string (&current_file_name, record_start->header.name);
 
 	  record_start->header.typeflag = GNUTYPE_VOLHDR;
-	  TIME_TO_OCT (time (0), record_start->header.mtime);
+	  TIME_TO_OCT (start_time, record_start->header.mtime);
 	  finish_header (record_start);
 #if 0
 	  current_block++;
diff -ru tar-1.13/src/common.h tar-1.13.1/src/common.h
--- tar-1.13/src/common.h	Wed Jul  7 08:07:30 1999
+++ tar-1.13.1/src/common.h	Mon Feb 21 23:30:56 2000
@@ -311,6 +311,12 @@
 
 /* Initial size of the sparsearray.  */
 GLOBAL int sp_array_size;
+
+/* Time of writing.  */
+GLOBAL time_t start_time;
+
+/* File to write record information to. */
+GLOBAL char *record_file_name;
 
 /* Declarations for each module.  */
 
@@ -327,7 +333,9 @@
 
 /* Module buffer.c.  */
 
+extern long baserec;
 extern FILE *stdlis;
+extern FILE *stdrec;
 extern char *save_name;
 extern off_t save_sizeleft;
 extern off_t save_totsize;
diff -ru tar-1.13/src/create.c tar-1.13.1/src/create.c
--- tar-1.13/src/create.c	Wed Jul  7 07:27:04 1999
+++ tar-1.13.1/src/create.c	Sun Aug  6 22:29:50 2000
@@ -435,11 +435,9 @@
 
   uintmax_to_oct ((uintmax_t) sum, header->header.chksum, 7);
 
-  set_next_block_after (header);
-
-  if (verbose_option
-      && header->header.typeflag != GNUTYPE_LONGLINK
-      && header->header.typeflag != GNUTYPE_LONGNAME)
+  if (verbose_option)
+      /* && header->header.typeflag != GNUTYPE_LONGLINK */
+      /* && header->header.typeflag != GNUTYPE_LONGNAME */
     {
       /* These globals are parameters to print_header, sigh.  */
 
@@ -448,6 +446,9 @@
       current_format = archive_format;
       print_header ();
     }
+
+  set_next_block_after (header);
+
 }
 
 /* Sparse file processing.  */
diff -ru tar-1.13/src/extract.c tar-1.13.1/src/extract.c
--- tar-1.13/src/extract.c	Fri Jul  2 23:24:36 1999
+++ tar-1.13.1/src/extract.c	Mon Feb 21 21:32:07 2000
@@ -962,6 +962,7 @@
     case GNUTYPE_LONGNAME:
     case GNUTYPE_LONGLINK:
       ERROR ((0, 0, _("Visible long name error")));
+      print_header();
       skip_file (current_stat.st_size);
       if (backup_option)
 	undo_last_backup ();
diff -ru tar-1.13/src/list.c tar-1.13.1/src/list.c
--- tar-1.13/src/list.c	Wed Jul  7 07:46:52 1999
+++ tar-1.13.1/src/list.c	Sun Aug  6 22:25:28 2000
@@ -124,7 +124,7 @@
 	  if (block_number_option)
 	    {
 	      char buf[UINTMAX_STRSIZE_BOUND];
-	      fprintf (stdlis, _("block %s: ** Block of NULs **\n"),
+	      fprintf (stdrec, _("block %s: ** Block of NULs **\n"),
 		       STRINGIFY_BIGINT (current_block_ordinal (), buf));
 	    }
 
@@ -138,7 +138,7 @@
 	  if (block_number_option)
 	    {
 	      char buf[UINTMAX_STRSIZE_BOUND];
-	      fprintf (stdlis, _("block %s: ** End of File **\n"),
+	      fprintf (stdrec, _("block %s: ** End of File **\n"),
 		       STRINGIFY_BIGINT (current_block_ordinal (), buf));
 	    }
 	  break;
@@ -217,7 +217,7 @@
 	  if (written > size)
 	    written = size;
 	  errno = 0;		/* FIXME: errno should be read-only */
-	  check = fwrite (data_block->buffer, sizeof (char), written, stdlis);
+	  check = fwrite (data_block->buffer, sizeof (char), written, stdrec);
 	  set_next_block_after ((union block *)
 				(data_block->buffer + written - 1));
 	  if (check != written)
@@ -231,8 +231,8 @@
 	}
       if (multi_volume_option)
 	assign_string (&save_name, NULL);
-      fputc ('\n', stdlis);
-      fflush (stdlis);
+      fputc ('\n', stdrec);
+      fflush (stdrec);
       return;
 
     }
@@ -381,6 +381,8 @@
 	  longp = ((header->header.typeflag == GNUTYPE_LONGNAME)
 		   ? &next_long_name
 		   : &next_long_link);
+          assign_string (&current_file_name, header->header.name);
+            print_header();
 
 	  set_next_block_after (header);
 	  if (*longp)
@@ -763,10 +765,18 @@
   int pad;
   char *name;
 
+  extern union block *record_start;
+  extern union block *current_block;
+  if (block_number_option)
+    fprintf (stdrec, _("rec %10ld: "), baserec + (current_block - record_start));
+#if 0
+  annofile (stdrec, (char *) NULL);
+#endif
+
   if (block_number_option)
     {
       char buf[UINTMAX_STRSIZE_BOUND];
-      fprintf (stdlis, _("block %s: "),
+      fprintf (stdrec, _("block %s: "),
 	       STRINGIFY_BIGINT (current_block_ordinal (), buf));
     }
 
@@ -778,11 +788,11 @@
 
       if (quoted_name)
 	{
-	  fprintf (stdlis, "%s\n", quoted_name);
+	  fprintf (stdrec, "%s\n", quoted_name);
 	  free (quoted_name);
 	}
       else
-	fprintf (stdlis, "%s\n", current_file_name);
+	fprintf (stdrec, "%s\n", current_file_name);
     }
   else
     {
@@ -792,6 +802,11 @@
       switch (current_header->header.typeflag)
 	{
 	case GNUTYPE_VOLHDR:
+          /* dirty bug fix to display the header processing
+           * tar cvvf /dev/null --label 'hello world' blah...
+           * J"org Weule weule@cs.uni-duesseldorf.de
+           */
+          current_stat.st_mtime = time_from_oct(current_block->header.mtime,1+12);
 	  modes[0] = 'V';
 	  break;
 
@@ -804,8 +819,12 @@
 	  break;
 
 	case GNUTYPE_LONGNAME:
+          modes[0] = 'L';
+          break;
+
 	case GNUTYPE_LONGLINK:
-	  ERROR ((0, 0, _("Visible longname error")));
+	  /* ERROR ((0, 0, _("Visible longname error"))); */
+          modes[0] = 'K' ;
 	  break;
 
 	case GNUTYPE_SPARSE:
@@ -898,22 +917,22 @@
 	ugswidth = pad;
 
 #if USE_OLD_CTIME
-      fprintf (stdlis, "%s %s/%s %*s%s %s %s",
+      fprintf (stdrec, "%s %s/%s %*s%s %s %s",
 	       modes, user, group, ugswidth - pad, "",
 	       size, timestamp + 4, timestamp + 20);
 #else
-      fprintf (stdlis, "%s %s/%s %*s%s %s",
+      fprintf (stdrec, "%s %s/%s %*s%s %s",
 	       modes, user, group, ugswidth - pad, "", size, timestamp);
 #endif
 
       name = quote_copy_string (current_file_name);
       if (name)
 	{
-	  fprintf (stdlis, " %s", name);
+	  fprintf (stdrec, " %s", name);
 	  free (name);
 	}
       else
-	fprintf (stdlis, " %s", current_file_name);
+	fprintf (stdrec, " %s", current_file_name);
 
       switch (current_header->header.typeflag)
 	{
@@ -921,26 +940,26 @@
 	  name = quote_copy_string (current_link_name);
 	  if (name)
 	    {
-	      fprintf (stdlis, " -> %s\n", name);
+	      fprintf (stdrec, " -> %s\n", name);
 	      free (name);
 	    }
 	  else
-	    fprintf (stdlis, " -> %s\n", current_link_name);
+	    fprintf (stdrec, " -> %s\n", current_link_name);
 	  break;
 
 	case LNKTYPE:
 	  name = quote_copy_string (current_link_name);
 	  if (name)
 	    {
-	      fprintf (stdlis, _(" link to %s\n"), name);
+	      fprintf (stdrec, _(" link to %s\n"), name);
 	      free (name);
 	    }
 	  else
-	    fprintf (stdlis, _(" link to %s\n"), current_link_name);
+	    fprintf (stdrec, _(" link to %s\n"), current_link_name);
 	  break;
 
 	default:
-	  fprintf (stdlis, _(" unknown file type `%c'\n"),
+	  fprintf (stdrec, _(" unknown file type `%c'\n"),
 		   current_header->header.typeflag);
 	  break;
 
@@ -953,11 +972,11 @@
 	case FIFOTYPE:
 	case CONTTYPE:
 	case GNUTYPE_DUMPDIR:
-	  putc ('\n', stdlis);
+	  putc ('\n', stdrec);
 	  break;
 
 	case GNUTYPE_VOLHDR:
-	  fprintf (stdlis, _("--Volume Header--\n"));
+	  fprintf (stdrec, _("--Volume Header--\n"));
 	  break;
 
 	case GNUTYPE_MULTIVOL:
@@ -965,15 +984,15 @@
 		  STRINGIFY_BIGINT
 		  (UINTMAX_FROM_OCT (current_header->oldgnu_header.offset),
 		   uintbuf));
-	  fprintf (stdlis, _("--Continued at byte %s--\n"), size);
+	  fprintf (stdrec, _("--Continued at byte %s--\n"), size);
 	  break;
 
 	case GNUTYPE_NAMES:
-	  fprintf (stdlis, _("--Mangled file names--\n"));
+	  fprintf (stdrec, _("--Mangled file names--\n"));
 	  break;
 	}
     }
-  fflush (stdlis);
+  fflush (stdrec);
 }
 
 /*--------------------------------------------------------------.
@@ -996,7 +1015,7 @@
       if (block_number_option)
 	{
 	  char buf[UINTMAX_STRSIZE_BOUND];
-	  fprintf (stdlis, _("block %s: "),
+	  fprintf (stdrec, _("block %s: "),
 		   STRINGIFY_BIGINT (current_block_ordinal (), buf));
 	}
       name = quote_copy_string (pathname);
diff -ru tar-1.13/src/names.c tar-1.13.1/src/names.c
--- tar-1.13/src/names.c	Wed Jul  7 07:46:51 1999
+++ tar-1.13.1/src/names.c	Sun Aug  6 22:20:43 2000
@@ -375,6 +375,14 @@
 	    FATAL_ERROR ((0, errno, _("Cannot change to directory %s"),
 			  name_buffer));
 	  chdir_flag = 0;
+          if ( record_file_name )
+            {
+              char *d = malloc(PATH_MAX);
+              if( d && getcwd(d,PATH_MAX) )
+                fprintf(stdrec,
+                        "loc             current directory is %s\n",
+                        d);
+            }
 	}
       else if (change_dirs && strcmp (name_buffer, "-C") == 0)
 	chdir_flag = 1;
diff -ru tar-1.13/src/tar.c tar-1.13.1/src/tar.c
--- tar-1.13/src/tar.c	Wed Jul  7 07:49:50 1999
+++ tar-1.13.1/src/tar.c	Tue Feb 22 00:27:07 2000
@@ -132,6 +132,7 @@
   SUFFIX_OPTION,
   USE_COMPRESS_PROGRAM_OPTION,
   VOLNO_FILE_OPTION,
+  RECORD_FILE_OPTION,
 
   /* Some cleanup is being made in GNU tar long options.  Using old names is
      allowed for a while, but will also send a warning to stderr.  Take old
@@ -220,6 +221,7 @@
   /* FIXME: --partial-blocks might be a synonym for --read-full-records?  */
   {"record-number", no_argument, NULL, OBSOLETE_BLOCK_NUMBER},
   {"record-size", required_argument, NULL, RECORD_SIZE_OPTION},
+  {"record-file", required_argument, NULL, RECORD_FILE_OPTION},
   {"remove-files", no_argument, &remove_files_option, 1},
   {"rsh-command", required_argument, NULL, RSH_COMMAND_OPTION},
   {"same-order", no_argument, NULL, 's'},
@@ -378,6 +380,7 @@
       --checkpoint      print directory names while reading the archive\n\
       --totals          print total bytes written while creating archive\n\
   -R, --block-number    show block number within archive with each message\n\
+      --record-file     print the record information to file, enable -R\n\
   -w, --interactive     ask for confirmation for every action\n\
       --confirmation    same as -w\n"),
 	     stdout);
@@ -904,6 +907,11 @@
 	volno_file_option = optarg;
 	break;
 
+      case RECORD_FILE_OPTION:
+        record_file_name = optarg ;
+        block_number_option++;         /* Print block #s for debug */
+        break;
+
       case USE_COMPRESS_PROGRAM_OPTION:
 	set_use_compress_program_option (optarg);
 	break;
@@ -1155,14 +1163,52 @@
       break;
 
     case CREATE_SUBCOMMAND:
+
+/*
+ * Comment the next line out if you have problems. Joerg Weule
+ */
+#define PRINT_TROUPUT
+#ifdef PRINT_TROUPUT
+      start_time = time(0);
       if (totals_option)
-	init_total_written ();
+        init_total_written ();
+      create_archive ();
+      if (totals_option) {
+        time_t end_time = time(0);
+        double sec = end_time - start_time ;
+        /* double t = ((double)total_written) * BLOCKSIZE ; */
+    	print_total_written ();
+        /*
+        fprintf (stderr, _("Total bytes written: %.0f"),t);
+        if ( t >= 1e9 ) fprintf(stderr, _(" (%3.1f Gb)"),t/1e9 ); else
+        if ( t >= 1e6 ) fprintf(stderr, _(" (%3.1f Mb)"),t/1e6 ); else
+        if ( t >= 1024 ) fprintf(stderr, _(" (%3.1f Kb)"),t/1024 );
+        fprintf(stderr,"\n");
+        if ( sec > 0.1 ){
+          long s, m, h = sec ;
+              m = h ;
+          h /= 3600 ;
+          m -= h * 3600 ;
+          s = m ;
+          m /= 60 ;
+          s -= m / 60 ;
+          fprintf (stderr, _("Elapsed time: %02d:%02d:%02d, %g sec\n"), h,m,s,sec);
+          if ( !flag_multivol)
+            fprintf (stderr, _("Throughput per second: %.0fKb/sec\n"),
+              t/sec/1024);
+        }
+        */
+      }
+#else
+      if (totals_option)
+        init_total_written ();
 
       create_archive ();
       name_close ();
 
       if (totals_option)
-	print_total_written ();
+        print_total_written ();
+#endif
       break;
 
     case EXTRACT_SUBCOMMAND:
