1/* Buffer management for tar.
2
3   Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
4   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5
6   Written by John Gilmore, on 1985-08-25.
7
8   This program is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by the
10   Free Software Foundation; either version 2, or (at your option) any later
11   version.
12
13   This program is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16   Public License for more details.
17
18   You should have received a copy of the GNU General Public License along
19   with this program; if not, write to the Free Software Foundation, Inc.,
20   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22#include <system.h>
23#include <system-ioctl.h>
24
25#include <signal.h>
26
27#include <closeout.h>
28#include <fnmatch.h>
29#include <getline.h>
30#include <human.h>
31#include <quotearg.h>
32
33#include "common.h"
34#include <rmt.h>
35
36/* Number of retries before giving up on read.  */
37#define	READ_ERROR_MAX 10
38
39/* Globbing pattern to append to volume label if initial match failed.  */
40#define VOLUME_LABEL_APPEND " Volume [1-9]*"
41
42/* Variables.  */
43
44static tarlong prev_written;	/* bytes written on previous volumes */
45static tarlong bytes_written;	/* bytes written on this volume */
46static void *record_buffer[2];	/* allocated memory */
47union block *record_buffer_aligned[2];
48static int record_index;
49
50/* FIXME: The following variables should ideally be static to this
51   module.  However, this cannot be done yet.  The cleanup continues!  */
52
53union block *record_start;	/* start of record of archive */
54union block *record_end;	/* last+1 block of archive record */
55union block *current_block;	/* current block of archive */
56enum access_mode access_mode;	/* how do we handle the archive */
57off_t records_read;		/* number of records read from this archive */
58off_t records_written;		/* likewise, for records written */
59extern off_t records_skipped;   /* number of records skipped at the start
60				   of the archive, defined in delete.c */
61
62static off_t record_start_block; /* block ordinal at record_start */
63
64/* Where we write list messages (not errors, not interactions) to.  */
65FILE *stdlis;
66
67static void backspace_output (void);
68
69/* PID of child program, if compress_option or remote archive access.  */
70static pid_t child_pid;
71
72/* Error recovery stuff  */
73static int read_error_count;
74
75/* Have we hit EOF yet?  */
76static bool hit_eof;
77
78/* Checkpointing counter */
79static unsigned checkpoint;
80
81static bool read_full_records = false;
82
83/* We're reading, but we just read the last block and it's time to update.
84   Declared in update.c
85
86   As least EXTERN like this one as possible. (?? --gray)
87   FIXME: Either eliminate it or move it to common.h.
88*/
89extern bool time_to_start_writing;
90
91bool write_archive_to_stdout;
92
93void (*flush_write_ptr) (size_t);
94void (*flush_read_ptr) (void);
95
96
97char *volume_label;
98char *continued_file_name;
99uintmax_t continued_file_size;
100uintmax_t continued_file_offset;
101
102
103static int volno = 1;		/* which volume of a multi-volume tape we're
104				   on */
105static int global_volno = 1;	/* volume number to print in external
106				   messages */
107
108bool write_archive_to_stdout;
109
110/* Used by flush_read and flush_write to store the real info about saved
111   names.  */
112static char *real_s_name;
113static off_t real_s_totsize;
114static off_t real_s_sizeleft;
115
116
117/* Multi-volume tracking support */
118static char *save_name;		/* name of the file we are currently writing */
119static off_t save_totsize;	/* total size of file we are writing, only
120				   valid if save_name is nonzero */
121static off_t save_sizeleft;	/* where we are in the file we are writing,
122				   only valid if save_name is nonzero */
123
124
125static struct tar_stat_info dummy;
126
127void
128buffer_write_global_xheader ()
129{
130  xheader_write_global (&dummy.xhdr);
131}
132
133void
134mv_begin (struct tar_stat_info *st)
135{
136  if (multi_volume_option)
137    {
138      assign_string (&save_name,  st->orig_file_name);
139      save_totsize = save_sizeleft = st->stat.st_size;
140    }
141}
142
143void
144mv_end ()
145{
146  if (multi_volume_option)
147    assign_string (&save_name, 0);
148}
149
150void
151mv_total_size (off_t size)
152{
153  save_totsize = size;
154}
155
156void
157mv_size_left (off_t size)
158{
159  save_sizeleft = size;
160}
161
162
163/* Functions.  */
164
165void
166clear_read_error_count (void)
167{
168  read_error_count = 0;
169}
170
171
172/* Time-related functions */
173
174double duration;
175
176void
177set_start_time ()
178{
179  gettime (&start_time);
180  volume_start_time = start_time;
181  last_stat_time = start_time;
182}
183
184void
185set_volume_start_time ()
186{
187  gettime (&volume_start_time);
188  last_stat_time = volume_start_time;
189}
190
191void
192compute_duration ()
193{
194  struct timespec now;
195  gettime (&now);
196  duration += ((now.tv_sec - last_stat_time.tv_sec)
197	       + (now.tv_nsec - last_stat_time.tv_nsec) / 1e9);
198  gettime (&last_stat_time);
199}
200
201
202/* Compression detection */
203
204enum compress_type {
205  ct_none,
206  ct_compress,
207  ct_gzip,
208  ct_bzip2
209};
210
211struct zip_magic
212{
213  enum compress_type type;
214  size_t length;
215  char *magic;
216  char *program;
217  char *option;
218};
219
220static struct zip_magic const magic[] = {
221  { ct_none, },
222  { ct_compress, 2, "\037\235", "compress", "-Z" },
223  { ct_gzip,     2, "\037\213", "gzip", "-z"  },
224  { ct_bzip2,    3, "BZh",      "bzip2", "-j" },
225};
226
227#define NMAGIC (sizeof(magic)/sizeof(magic[0]))
228
229#define compress_option(t) magic[t].option
230#define compress_program(t) magic[t].program
231
232/* Check if the file ARCHIVE is a compressed archive. */
233enum compress_type
234check_compressed_archive ()
235{
236  struct zip_magic const *p;
237  bool sfr;
238
239  /* Prepare global data needed for find_next_block: */
240  record_end = record_start; /* set up for 1st record = # 0 */
241  sfr = read_full_records;
242  read_full_records = true; /* Suppress fatal error on reading a partial
243			       record */
244  find_next_block ();
245
246  /* Restore global values */
247  read_full_records = sfr;
248
249  if (tar_checksum (record_start, true) == HEADER_SUCCESS)
250    /* Probably a valid header */
251    return ct_none;
252
253  for (p = magic + 1; p < magic + NMAGIC; p++)
254    if (memcmp (record_start->buffer, p->magic, p->length) == 0)
255      return p->type;
256
257  return ct_none;
258}
259
260/* Open an archive named archive_name_array[0]. Detect if it is
261   a compressed archive of known type and use corresponding decompression
262   program if so */
263int
264open_compressed_archive ()
265{
266  archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
267		     MODE_RW, rsh_command_option);
268  if (archive == -1)
269    return archive;
270
271  if (!multi_volume_option)
272    {
273      enum compress_type type = check_compressed_archive ();
274
275      if (type == ct_none)
276	return archive;
277
278      /* FD is not needed any more */
279      rmtclose (archive);
280
281      hit_eof = false; /* It might have been set by find_next_block in
282			  check_compressed_archive */
283
284      /* Open compressed archive */
285      use_compress_program_option = compress_program (type);
286      child_pid = sys_child_open_for_uncompress ();
287      read_full_records = true;
288    }
289
290  records_read = 0;
291  record_end = record_start; /* set up for 1st record = # 0 */
292
293  return archive;
294}
295
296
297static void
298print_stats (FILE *fp, const char *text, tarlong numbytes)
299{
300  char bytes[sizeof (tarlong) * CHAR_BIT];
301  char abbr[LONGEST_HUMAN_READABLE + 1];
302  char rate[LONGEST_HUMAN_READABLE + 1];
303
304  int human_opts = human_autoscale | human_base_1024 | human_SI | human_B;
305
306  sprintf (bytes, TARLONG_FORMAT, numbytes);
307
308  fprintf (fp, "%s: %s (%s, %s/s)\n",
309	   text, bytes,
310	   human_readable (numbytes, abbr, human_opts, 1, 1),
311	   (0 < duration && numbytes / duration < (uintmax_t) -1
312	    ? human_readable (numbytes / duration, rate, human_opts, 1, 1)
313	    : "?"));
314}
315
316void
317print_total_stats ()
318{
319  switch (subcommand_option)
320    {
321    case CREATE_SUBCOMMAND:
322    case CAT_SUBCOMMAND:
323    case UPDATE_SUBCOMMAND:
324    case APPEND_SUBCOMMAND:
325      /* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*".  */
326      print_stats (stderr, _("Total bytes written"),
327		   prev_written + bytes_written);
328      break;
329
330    case DELETE_SUBCOMMAND:
331      {
332	char buf[UINTMAX_STRSIZE_BOUND];
333	print_stats (stderr, _("Total bytes read"),
334		     records_read * record_size);
335	print_stats (stderr, _("Total bytes written"),
336		     prev_written + bytes_written);
337	fprintf (stderr, _("Total bytes deleted: %s\n"),
338		 STRINGIFY_BIGINT ((records_read - records_skipped)
339				    * record_size
340				   - (prev_written + bytes_written), buf));
341      }
342      break;
343
344    case EXTRACT_SUBCOMMAND:
345    case LIST_SUBCOMMAND:
346    case DIFF_SUBCOMMAND:
347      print_stats (stderr, _("Total bytes read"),
348		   records_read * record_size);
349      break;
350
351    default:
352      abort ();
353    }
354}
355
356/* Compute and return the block ordinal at current_block.  */
357off_t
358current_block_ordinal (void)
359{
360  return record_start_block + (current_block - record_start);
361}
362
363/* If the EOF flag is set, reset it, as well as current_block, etc.  */
364void
365reset_eof (void)
366{
367  if (hit_eof)
368    {
369      hit_eof = false;
370      current_block = record_start;
371      record_end = record_start + blocking_factor;
372      access_mode = ACCESS_WRITE;
373    }
374}
375
376/* Return the location of the next available input or output block.
377   Return zero for EOF.  Once we have returned zero, we just keep returning
378   it, to avoid accidentally going on to the next file on the tape.  */
379union block *
380find_next_block (void)
381{
382  if (current_block == record_end)
383    {
384      if (hit_eof)
385	return 0;
386      flush_archive ();
387      if (current_block == record_end)
388	{
389	  hit_eof = true;
390	  return 0;
391	}
392    }
393  return current_block;
394}
395
396/* Indicate that we have used all blocks up thru BLOCK. */
397void
398set_next_block_after (union block *block)
399{
400  while (block >= current_block)
401    current_block++;
402
403  /* Do *not* flush the archive here.  If we do, the same argument to
404     set_next_block_after could mean the next block (if the input record
405     is exactly one block long), which is not what is intended.  */
406
407  if (current_block > record_end)
408    abort ();
409}
410
411/* Return the number of bytes comprising the space between POINTER
412   through the end of the current buffer of blocks.  This space is
413   available for filling with data, or taking data from.  POINTER is
414   usually (but not always) the result of previous find_next_block call.  */
415size_t
416available_space_after (union block *pointer)
417{
418  return record_end->buffer - pointer->buffer;
419}
420
421/* Close file having descriptor FD, and abort if close unsuccessful.  */
422void
423xclose (int fd)
424{
425  if (close (fd) != 0)
426    close_error (_("(pipe)"));
427}
428
429static void
430init_buffer ()
431{
432  if (! record_buffer_aligned[record_index])
433    record_buffer_aligned[record_index] =
434      page_aligned_alloc (&record_buffer[record_index], record_size);
435
436  record_start = record_buffer_aligned[record_index];
437  current_block = record_start;
438  record_end = record_start + blocking_factor;
439}
440
441#if HAVE_QUARANTINE
442void
443init_qtn(const char *file_name)
444{
445	int fd;
446
447	if (strcmp(file_name, "-") == 0)
448		return;
449
450	if ((fd = open(file_name, O_RDONLY)) < 0)
451		return;
452
453	if ((archive_qtn_file = qtn_file_alloc()) != NULL) {
454		if (qtn_file_init_with_fd(archive_qtn_file, fd) != 0) {
455			qtn_file_free(archive_qtn_file);
456			archive_qtn_file = NULL;
457		}
458	}
459
460	close(fd);
461}
462
463void
464finish_qtn(void)
465{
466	if (archive_qtn_file != NULL) {
467		qtn_file_free(archive_qtn_file);
468		archive_qtn_file = NULL;
469	}
470}
471#else
472void init_qtn(const char *file_name) {}
473void finish_qtn(void) {}
474#endif
475
476/* Open an archive file.  The argument specifies whether we are
477   reading or writing, or both.  */
478static void
479_open_archive (enum access_mode wanted_access)
480{
481  int backed_up_flag = 0;
482
483  if (record_size == 0)
484    FATAL_ERROR ((0, 0, _("Invalid value for record_size")));
485
486  if (archive_names == 0)
487    FATAL_ERROR ((0, 0, _("No archive name given")));
488
489  tar_stat_destroy (&current_stat_info);
490  save_name = 0;
491  real_s_name = 0;
492
493  record_index = 0;
494  init_buffer ();
495
496  /* When updating the archive, we start with reading.  */
497  access_mode = wanted_access == ACCESS_UPDATE ? ACCESS_READ : wanted_access;
498
499  read_full_records = read_full_records_option;
500
501  records_read = 0;
502
503  if (use_compress_program_option)
504    {
505      switch (wanted_access)
506	{
507	case ACCESS_READ:
508	  child_pid = sys_child_open_for_uncompress ();
509	  read_full_records = true;
510	  record_end = record_start; /* set up for 1st record = # 0 */
511	  break;
512
513	case ACCESS_WRITE:
514	  child_pid = sys_child_open_for_compress ();
515	  break;
516
517	case ACCESS_UPDATE:
518	  abort (); /* Should not happen */
519	  break;
520	}
521
522      if (!index_file_name
523	  && wanted_access == ACCESS_WRITE
524	  && strcmp (archive_name_array[0], "-") == 0)
525	stdlis = stderr;
526    }
527  else if (strcmp (archive_name_array[0], "-") == 0)
528    {
529      read_full_records = true; /* could be a pipe, be safe */
530      if (verify_option)
531	FATAL_ERROR ((0, 0, _("Cannot verify stdin/stdout archive")));
532
533      switch (wanted_access)
534	{
535	case ACCESS_READ:
536	  {
537	    enum compress_type type;
538
539	    archive = STDIN_FILENO;
540
541	    type = check_compressed_archive ();
542	    if (type != ct_none)
543	      FATAL_ERROR ((0, 0,
544			    _("Archive is compressed. Use %s option"),
545			    compress_option (type)));
546	  }
547	  break;
548
549	case ACCESS_WRITE:
550	  archive = STDOUT_FILENO;
551	  if (!index_file_name)
552	    stdlis = stderr;
553	  break;
554
555	case ACCESS_UPDATE:
556	  archive = STDIN_FILENO;
557	  write_archive_to_stdout = true;
558	  record_end = record_start; /* set up for 1st record = # 0 */
559	  if (!index_file_name)
560	    stdlis = stderr;
561	  break;
562	}
563    }
564  else if (verify_option)
565    archive = rmtopen (archive_name_array[0], O_RDWR | O_CREAT | O_BINARY,
566		       MODE_RW, rsh_command_option);
567  else
568    switch (wanted_access)
569      {
570      case ACCESS_READ:
571	archive = open_compressed_archive ();
572	break;
573
574      case ACCESS_WRITE:
575	if (backup_option)
576	  {
577	    maybe_backup_file (archive_name_array[0], 1);
578	    backed_up_flag = 1;
579	  }
580	archive = rmtcreat (archive_name_array[0], MODE_RW,
581			    rsh_command_option);
582	break;
583
584      case ACCESS_UPDATE:
585	archive = rmtopen (archive_name_array[0],
586			   O_RDWR | O_CREAT | O_BINARY,
587			   MODE_RW, rsh_command_option);
588
589	if (check_compressed_archive () != ct_none)
590	  FATAL_ERROR ((0, 0,
591			_("Cannot update compressed archives")));
592	break;
593      }
594
595  if (archive < 0
596      || (! _isrmt (archive) && !sys_get_archive_stat ()))
597    {
598      int saved_errno = errno;
599
600      if (backed_up_flag)
601	undo_last_backup ();
602      errno = saved_errno;
603      open_fatal (archive_name_array[0]);
604    }
605
606  sys_detect_dev_null_output ();
607  sys_save_archive_dev_ino ();
608  SET_BINARY_MODE (archive);
609  init_qtn(archive_name_array[0]);
610
611  switch (wanted_access)
612    {
613    case ACCESS_READ:
614      find_next_block ();	/* read it in, check for EOF */
615      break;
616
617    case ACCESS_UPDATE:
618    case ACCESS_WRITE:
619      records_written = 0;
620      break;
621    }
622}
623
624static void
625do_checkpoint (bool write)
626{
627  if (checkpoint_option && !(++checkpoint % checkpoint_option))
628    {
629      switch (checkpoint_style)
630	{
631	case checkpoint_dot:
632	  fputc ('.', stdlis);
633	  fflush (stdlis);
634	  break;
635
636	case checkpoint_text:
637	  if (write)
638	    /* TRANSLATORS: This is a ``checkpoint of write operation'',
639	     *not* ``Writing a checkpoint''.
640	     E.g. in Spanish ``Punto de comprobaci@'on de escritura'',
641	     *not* ``Escribiendo un punto de comprobaci@'on'' */
642	    WARN ((0, 0, _("Write checkpoint %u"), checkpoint));
643	  else
644	    /* TRANSLATORS: This is a ``checkpoint of read operation'',
645	       *not* ``Reading a checkpoint''.
646	       E.g. in Spanish ``Punto de comprobaci@'on de lectura'',
647	       *not* ``Leyendo un punto de comprobaci@'on'' */
648	    WARN ((0, 0, _("Read checkpoint %u"), checkpoint));
649	  break;
650	}
651    }
652}
653
654/* Perform a write to flush the buffer.  */
655ssize_t
656_flush_write (void)
657{
658  ssize_t status;
659
660  do_checkpoint (true);
661  if (tape_length_option && tape_length_option <= bytes_written)
662    {
663      errno = ENOSPC;
664      status = 0;
665    }
666  else if (dev_null_output)
667    status = record_size;
668  else
669    status = sys_write_archive_buffer ();
670
671  return status;
672}
673
674/* Handle write errors on the archive.  Write errors are always fatal.
675   Hitting the end of a volume does not cause a write error unless the
676   write was the first record of the volume.  */
677void
678archive_write_error (ssize_t status)
679{
680  /* It might be useful to know how much was written before the error
681     occurred.  */
682  if (totals_option)
683    {
684      int e = errno;
685      print_total_stats ();
686      errno = e;
687    }
688
689  write_fatal_details (*archive_name_cursor, status, record_size);
690}
691
692/* Handle read errors on the archive.  If the read should be retried,
693   return to the caller.  */
694void
695archive_read_error (void)
696{
697  read_error (*archive_name_cursor);
698
699  if (record_start_block == 0)
700    FATAL_ERROR ((0, 0, _("At beginning of tape, quitting now")));
701
702  /* Read error in mid archive.  We retry up to READ_ERROR_MAX times and
703     then give up on reading the archive.  */
704
705  if (read_error_count++ > READ_ERROR_MAX)
706    FATAL_ERROR ((0, 0, _("Too many errors, quitting")));
707  return;
708}
709
710static void
711short_read (size_t status)
712{
713  size_t left;			/* bytes left */
714  char *more;			/* pointer to next byte to read */
715
716  more = record_start->buffer + status;
717  left = record_size - status;
718
719  while (left % BLOCKSIZE != 0
720	 || (left && status && read_full_records))
721    {
722      if (status)
723	while ((status = rmtread (archive, more, left)) == SAFE_READ_ERROR)
724	  archive_read_error ();
725
726      if (status == 0)
727	break;
728
729      if (! read_full_records)
730	{
731	  unsigned long rest = record_size - left;
732
733	  FATAL_ERROR ((0, 0,
734			ngettext ("Unaligned block (%lu byte) in archive",
735				  "Unaligned block (%lu bytes) in archive",
736				  rest),
737			rest));
738	}
739
740      /* User warned us about this.  Fix up.  */
741
742      left -= status;
743      more += status;
744    }
745
746  /* FIXME: for size=0, multi-volume support.  On the first record, warn
747     about the problem.  */
748
749  if (!read_full_records && verbose_option > 1
750      && record_start_block == 0 && status != 0)
751    {
752      unsigned long rsize = (record_size - left) / BLOCKSIZE;
753      WARN ((0, 0,
754	     ngettext ("Record size = %lu block",
755		       "Record size = %lu blocks",
756		       rsize),
757	     rsize));
758    }
759
760  record_end = record_start + (record_size - left) / BLOCKSIZE;
761  records_read++;
762}
763
764/*  Flush the current buffer to/from the archive.  */
765void
766flush_archive (void)
767{
768  size_t buffer_level = current_block->buffer - record_start->buffer;
769  record_start_block += record_end - record_start;
770  current_block = record_start;
771  record_end = record_start + blocking_factor;
772
773  if (access_mode == ACCESS_READ && time_to_start_writing)
774    {
775      access_mode = ACCESS_WRITE;
776      time_to_start_writing = false;
777      backspace_output ();
778    }
779
780  switch (access_mode)
781    {
782    case ACCESS_READ:
783      flush_read ();
784      break;
785
786    case ACCESS_WRITE:
787      flush_write_ptr (buffer_level);
788      break;
789
790    case ACCESS_UPDATE:
791      abort ();
792    }
793}
794
795/* Backspace the archive descriptor by one record worth.  If it's a
796   tape, MTIOCTOP will work.  If it's something else, try to seek on
797   it.  If we can't seek, we lose!  */
798static void
799backspace_output (void)
800{
801#ifdef MTIOCTOP
802  {
803    struct mtop operation;
804
805    operation.mt_op = MTBSR;
806    operation.mt_count = 1;
807    if (rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0)
808      return;
809    if (errno == EIO && rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0)
810      return;
811  }
812#endif
813
814  {
815    off_t position = rmtlseek (archive, (off_t) 0, SEEK_CUR);
816
817    /* Seek back to the beginning of this record and start writing there.  */
818
819    position -= record_size;
820    if (position < 0)
821      position = 0;
822    if (rmtlseek (archive, position, SEEK_SET) != position)
823      {
824	/* Lseek failed.  Try a different method.  */
825
826	WARN ((0, 0,
827	       _("Cannot backspace archive file; it may be unreadable without -i")));
828
829	/* Replace the first part of the record with NULs.  */
830
831	if (record_start->buffer != output_start)
832	  memset (record_start->buffer, 0,
833		  output_start - record_start->buffer);
834      }
835  }
836}
837
838off_t
839seek_archive (off_t size)
840{
841  off_t start = current_block_ordinal ();
842  off_t offset;
843  off_t nrec, nblk;
844  off_t skipped = (blocking_factor - (current_block - record_start));
845
846  size -= skipped * BLOCKSIZE;
847
848  if (size < record_size)
849    return 0;
850  /* FIXME: flush? */
851
852  /* Compute number of records to skip */
853  nrec = size / record_size;
854  offset = rmtlseek (archive, nrec * record_size, SEEK_CUR);
855  if (offset < 0)
856    return offset;
857
858  if (offset % record_size)
859    FATAL_ERROR ((0, 0, _("rmtlseek not stopped at a record boundary")));
860
861  /* Convert to number of records */
862  offset /= BLOCKSIZE;
863  /* Compute number of skipped blocks */
864  nblk = offset - start;
865
866  /* Update buffering info */
867  records_read += nblk / blocking_factor;
868  record_start_block = offset - blocking_factor;
869  current_block = record_end;
870
871  return nblk;
872}
873
874/* Close the archive file.  */
875void
876close_archive (void)
877{
878  if (time_to_start_writing || access_mode == ACCESS_WRITE)
879    {
880      flush_archive ();
881      if (current_block > record_start)
882	flush_archive ();
883    }
884
885  sys_drain_input_pipe ();
886
887  compute_duration ();
888  if (verify_option)
889    verify_volume ();
890
891  if (rmtclose (archive) != 0)
892    close_warn (*archive_name_cursor);
893
894  sys_wait_for_child (child_pid);
895
896  tar_stat_destroy (&current_stat_info);
897  if (save_name)
898    free (save_name);
899  if (real_s_name)
900    free (real_s_name);
901  free (record_buffer[0]);
902  free (record_buffer[1]);
903
904  finish_qtn();
905}
906
907/* Called to initialize the global volume number.  */
908void
909init_volume_number (void)
910{
911  FILE *file = fopen (volno_file_option, "r");
912
913  if (file)
914    {
915      if (fscanf (file, "%d", &global_volno) != 1
916	  || global_volno < 0)
917	FATAL_ERROR ((0, 0, _("%s: contains invalid volume number"),
918		      quotearg_colon (volno_file_option)));
919      if (ferror (file))
920	read_error (volno_file_option);
921      if (fclose (file) != 0)
922	close_error (volno_file_option);
923    }
924  else if (errno != ENOENT)
925    open_error (volno_file_option);
926}
927
928/* Called to write out the closing global volume number.  */
929void
930closeout_volume_number (void)
931{
932  FILE *file = fopen (volno_file_option, "w");
933
934  if (file)
935    {
936      fprintf (file, "%d\n", global_volno);
937      if (ferror (file))
938	write_error (volno_file_option);
939      if (fclose (file) != 0)
940	close_error (volno_file_option);
941    }
942  else
943    open_error (volno_file_option);
944}
945
946
947static void
948increase_volume_number ()
949{
950  global_volno++;
951  if (global_volno < 0)
952    FATAL_ERROR ((0, 0, _("Volume number overflow")));
953  volno++;
954}
955
956void
957change_tape_menu (FILE *read_file)
958{
959  char *input_buffer = NULL;
960  size_t size = 0;
961  bool stop = false;
962
963  while (!stop)
964    {
965      fputc ('\007', stderr);
966      fprintf (stderr,
967	       _("Prepare volume #%d for %s and hit return: "),
968	       global_volno + 1, quote (*archive_name_cursor));
969      fflush (stderr);
970
971      if (getline (&input_buffer, &size, read_file) <= 0)
972	{
973	  WARN ((0, 0, _("EOF where user reply was expected")));
974
975	  if (subcommand_option != EXTRACT_SUBCOMMAND
976	      && subcommand_option != LIST_SUBCOMMAND
977	      && subcommand_option != DIFF_SUBCOMMAND)
978	    WARN ((0, 0, _("WARNING: Archive is incomplete")));
979
980	  fatal_exit ();
981	}
982
983      if (input_buffer[0] == '\n'
984	  || input_buffer[0] == 'y'
985	  || input_buffer[0] == 'Y')
986	break;
987
988      switch (input_buffer[0])
989	{
990	case '?':
991	  {
992	    fprintf (stderr, _("\
993 n name        Give a new file name for the next (and subsequent) volume(s)\n\
994 q             Abort tar\n\
995 y or newline  Continue operation\n"));
996            if (!restrict_option)
997              fprintf (stderr, _(" !             Spawn a subshell\n"));
998	    fprintf (stderr, _(" ?             Print this list\n"));
999	  }
1000	  break;
1001
1002	case 'q':
1003	  /* Quit.  */
1004
1005	  WARN ((0, 0, _("No new volume; exiting.\n")));
1006
1007	  if (subcommand_option != EXTRACT_SUBCOMMAND
1008	      && subcommand_option != LIST_SUBCOMMAND
1009	      && subcommand_option != DIFF_SUBCOMMAND)
1010	    WARN ((0, 0, _("WARNING: Archive is incomplete")));
1011
1012	  fatal_exit ();
1013
1014	case 'n':
1015	  /* Get new file name.  */
1016
1017	  {
1018	    char *name;
1019	    char *cursor;
1020
1021	    for (name = input_buffer + 1;
1022		 *name == ' ' || *name == '\t';
1023		 name++)
1024	      ;
1025
1026	    for (cursor = name; *cursor && *cursor != '\n'; cursor++)
1027	      ;
1028	    *cursor = '\0';
1029
1030	    if (name[0])
1031	      {
1032		/* FIXME: the following allocation is never reclaimed.  */
1033		*archive_name_cursor = xstrdup (name);
1034		stop = true;
1035	      }
1036	    else
1037	      fprintf (stderr, "%s",
1038		       _("File name not specified. Try again.\n"));
1039	  }
1040	  break;
1041
1042	case '!':
1043	  if (!restrict_option)
1044	    {
1045	      sys_spawn_shell ();
1046	      break;
1047	    }
1048	  /* FALL THROUGH */
1049
1050	default:
1051	  fprintf (stderr, _("Invalid input. Type ? for help.\n"));
1052	}
1053    }
1054  free (input_buffer);
1055}
1056
1057/* We've hit the end of the old volume.  Close it and open the next one.
1058   Return nonzero on success.
1059*/
1060static bool
1061new_volume (enum access_mode mode)
1062{
1063  static FILE *read_file;
1064  static int looped;
1065  int prompt;
1066
1067  if (!read_file && !info_script_option)
1068    /* FIXME: if fopen is used, it will never be closed.  */
1069    read_file = archive == STDIN_FILENO ? fopen (TTY_NAME, "r") : stdin;
1070
1071  if (now_verifying)
1072    return false;
1073  if (verify_option)
1074    verify_volume ();
1075
1076  assign_string (&volume_label, NULL);
1077  assign_string (&continued_file_name, NULL);
1078  continued_file_size = continued_file_offset = 0;
1079  current_block = record_start;
1080
1081  if (rmtclose (archive) != 0)
1082    close_warn (*archive_name_cursor);
1083
1084  archive_name_cursor++;
1085  if (archive_name_cursor == archive_name_array + archive_names)
1086    {
1087      archive_name_cursor = archive_name_array;
1088      looped = 1;
1089    }
1090  prompt = looped;
1091
1092 tryagain:
1093  if (prompt)
1094    {
1095      /* We have to prompt from now on.  */
1096
1097      if (info_script_option)
1098	{
1099	  if (volno_file_option)
1100	    closeout_volume_number ();
1101	  if (sys_exec_info_script (archive_name_cursor, global_volno+1))
1102	    FATAL_ERROR ((0, 0, _("%s command failed"),
1103			  quote (info_script_option)));
1104	}
1105      else
1106	change_tape_menu (read_file);
1107    }
1108
1109  if (strcmp (archive_name_cursor[0], "-") == 0)
1110    {
1111      read_full_records = true;
1112      archive = STDIN_FILENO;
1113    }
1114  else if (verify_option)
1115    archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
1116		       rsh_command_option);
1117  else
1118    switch (mode)
1119      {
1120      case ACCESS_READ:
1121	archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW,
1122			   rsh_command_option);
1123	break;
1124
1125      case ACCESS_WRITE:
1126	if (backup_option)
1127	  maybe_backup_file (*archive_name_cursor, 1);
1128	archive = rmtcreat (*archive_name_cursor, MODE_RW,
1129			    rsh_command_option);
1130	break;
1131
1132      case ACCESS_UPDATE:
1133	archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
1134			   rsh_command_option);
1135	break;
1136      }
1137
1138  if (archive < 0)
1139    {
1140      open_warn (*archive_name_cursor);
1141      if (!verify_option && mode == ACCESS_WRITE && backup_option)
1142	undo_last_backup ();
1143      prompt = 1;
1144      goto tryagain;
1145    }
1146
1147  SET_BINARY_MODE (archive);
1148
1149  return true;
1150}
1151
1152static bool
1153read_header0 (struct tar_stat_info *info)
1154{
1155  enum read_header rc;
1156
1157  tar_stat_init (info);
1158  rc = read_header_primitive (false, info);
1159  if (rc == HEADER_SUCCESS)
1160    {
1161      set_next_block_after (current_header);
1162      return true;
1163    }
1164  ERROR ((0, 0, _("This does not look like a tar archive")));
1165  return false;
1166}
1167
1168bool
1169try_new_volume ()
1170{
1171  size_t status;
1172  union block *header;
1173  int access;
1174
1175  switch (subcommand_option)
1176    {
1177    case APPEND_SUBCOMMAND:
1178    case CAT_SUBCOMMAND:
1179    case UPDATE_SUBCOMMAND:
1180      access = ACCESS_UPDATE;
1181      break;
1182
1183    default:
1184      access = ACCESS_READ;
1185      break;
1186    }
1187
1188  if (!new_volume (access))
1189    return true;
1190
1191  while ((status = rmtread (archive, record_start->buffer, record_size))
1192	 == SAFE_READ_ERROR)
1193    archive_read_error ();
1194
1195  if (status != record_size)
1196    short_read (status);
1197
1198  header = find_next_block ();
1199  if (!header)
1200    return false;
1201
1202  switch (header->header.typeflag)
1203    {
1204    case XGLTYPE:
1205      {
1206	if (!read_header0 (&dummy))
1207	  return false;
1208	xheader_decode (&dummy); /* decodes values from the global header */
1209	tar_stat_destroy (&dummy);
1210	if (!real_s_name)
1211	  {
1212	    /* We have read the extended header of the first member in
1213	       this volume. Put it back, so next read_header works as
1214	       expected. */
1215	    current_block = record_start;
1216	  }
1217	break;
1218      }
1219
1220    case GNUTYPE_VOLHDR:
1221      if (!read_header0 (&dummy))
1222	return false;
1223      tar_stat_destroy (&dummy);
1224      assign_string (&volume_label, current_header->header.name);
1225      set_next_block_after (header);
1226      header = find_next_block ();
1227      if (header->header.typeflag != GNUTYPE_MULTIVOL)
1228	break;
1229      /* FALL THROUGH */
1230
1231    case GNUTYPE_MULTIVOL:
1232      if (!read_header0 (&dummy))
1233	return false;
1234      tar_stat_destroy (&dummy);
1235      assign_string (&continued_file_name, current_header->header.name);
1236      continued_file_size =
1237	UINTMAX_FROM_HEADER (current_header->header.size);
1238      continued_file_offset =
1239	UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset);
1240      break;
1241
1242    default:
1243      break;
1244    }
1245
1246  if (real_s_name)
1247    {
1248      uintmax_t s;
1249      if (!continued_file_name
1250	  || strcmp (continued_file_name, real_s_name))
1251	{
1252	  if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
1253	      && strlen (real_s_name) >= NAME_FIELD_SIZE
1254	      && strncmp (continued_file_name, real_s_name,
1255			  NAME_FIELD_SIZE) == 0)
1256	    WARN ((0, 0,
1257 _("%s is possibly continued on this volume: header contains truncated name"),
1258		   quote (real_s_name)));
1259	  else
1260	    {
1261	      WARN ((0, 0, _("%s is not continued on this volume"),
1262		     quote (real_s_name)));
1263	      return false;
1264	    }
1265	}
1266
1267      s = continued_file_size + continued_file_offset;
1268
1269      if (real_s_totsize != s || s < continued_file_offset)
1270	{
1271	  char totsizebuf[UINTMAX_STRSIZE_BOUND];
1272	  char s1buf[UINTMAX_STRSIZE_BOUND];
1273	  char s2buf[UINTMAX_STRSIZE_BOUND];
1274
1275	  WARN ((0, 0, _("%s is the wrong size (%s != %s + %s)"),
1276		 quote (continued_file_name),
1277		 STRINGIFY_BIGINT (save_totsize, totsizebuf),
1278		 STRINGIFY_BIGINT (continued_file_size, s1buf),
1279		 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
1280	  return false;
1281	}
1282
1283      if (real_s_totsize - real_s_sizeleft != continued_file_offset)
1284	{
1285	  WARN ((0, 0, _("This volume is out of sequence")));
1286	  return false;
1287	}
1288    }
1289
1290  increase_volume_number ();
1291  return true;
1292}
1293
1294
1295/* Check the LABEL block against the volume label, seen as a globbing
1296   pattern.  Return true if the pattern matches.  In case of failure,
1297   retry matching a volume sequence number before giving up in
1298   multi-volume mode.  */
1299static bool
1300check_label_pattern (union block *label)
1301{
1302  char *string;
1303  bool result;
1304
1305  if (! memchr (label->header.name, '\0', sizeof label->header.name))
1306    return false;
1307
1308  if (fnmatch (volume_label_option, label->header.name, 0) == 0)
1309    return true;
1310
1311  if (!multi_volume_option)
1312    return false;
1313
1314  string = xmalloc (strlen (volume_label_option)
1315		    + sizeof VOLUME_LABEL_APPEND + 1);
1316  strcpy (string, volume_label_option);
1317  strcat (string, VOLUME_LABEL_APPEND);
1318  result = fnmatch (string, label->header.name, 0) == 0;
1319  free (string);
1320  return result;
1321}
1322
1323/* Check if the next block contains a volume label and if this matches
1324   the one given in the command line */
1325static void
1326match_volume_label (void)
1327{
1328  union block *label = find_next_block ();
1329
1330  if (!label)
1331    FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
1332		  quote (volume_label_option)));
1333  if (!check_label_pattern (label))
1334    FATAL_ERROR ((0, 0, _("Volume %s does not match %s"),
1335		  quote_n (0, label->header.name),
1336		  quote_n (1, volume_label_option)));
1337}
1338
1339/* Mark the archive with volume label STR. */
1340static void
1341_write_volume_label (const char *str)
1342{
1343  if (archive_format == POSIX_FORMAT)
1344    xheader_store ("GNU.volume.label", &dummy, str);
1345  else
1346    {
1347      union block *label = find_next_block ();
1348
1349      memset (label, 0, BLOCKSIZE);
1350
1351      strcpy (label->header.name, volume_label_option);
1352      assign_string (&current_stat_info.file_name,
1353		     label->header.name);
1354      current_stat_info.had_trailing_slash =
1355	strip_trailing_slashes (current_stat_info.file_name);
1356
1357      label->header.typeflag = GNUTYPE_VOLHDR;
1358      TIME_TO_CHARS (start_time.tv_sec, label->header.mtime);
1359      finish_header (&current_stat_info, label, -1);
1360      set_next_block_after (label);
1361    }
1362}
1363
1364#define VOL_SUFFIX "Volume"
1365
1366/* Add a volume label to a part of multi-volume archive */
1367static void
1368add_volume_label (void)
1369{
1370  char buf[UINTMAX_STRSIZE_BOUND];
1371  char *p = STRINGIFY_BIGINT (volno, buf);
1372  char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX
1373		     + strlen (p) + 2);
1374  sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p);
1375  _write_volume_label (s);
1376  free (s);
1377}
1378
1379static void
1380add_chunk_header ()
1381{
1382  if (archive_format == POSIX_FORMAT)
1383    {
1384      off_t block_ordinal;
1385      union block *blk;
1386      struct tar_stat_info st;
1387      static size_t real_s_part_no; /* FIXME */
1388
1389      real_s_part_no++;
1390      memset (&st, 0, sizeof st);
1391      st.orig_file_name = st.file_name = real_s_name;
1392      st.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
1393      st.stat.st_uid = getuid ();
1394      st.stat.st_gid = getgid ();
1395      st.orig_file_name = xheader_format_name (&st,
1396					       "%d/GNUFileParts.%p/%f.%n",
1397					       real_s_part_no);
1398      st.file_name = st.orig_file_name;
1399      st.archive_file_size = st.stat.st_size = real_s_sizeleft;
1400
1401      block_ordinal = current_block_ordinal ();
1402      blk = start_header (&st);
1403      if (!blk)
1404	abort (); /* FIXME */
1405      finish_header (&st, blk, block_ordinal);
1406      free (st.orig_file_name);
1407    }
1408}
1409
1410
1411/* Add a volume label to the current archive */
1412static void
1413write_volume_label (void)
1414{
1415  if (multi_volume_option)
1416    add_volume_label ();
1417  else
1418    _write_volume_label (volume_label_option);
1419}
1420
1421/* Write GNU multi-volume header */
1422static void
1423gnu_add_multi_volume_header (void)
1424{
1425  int tmp;
1426  union block *block = find_next_block ();
1427
1428  if (strlen (real_s_name) > NAME_FIELD_SIZE)
1429    WARN ((0, 0,
1430	   _("%s: file name too long to be stored in a GNU multivolume header, truncated"),
1431	   quotearg_colon (real_s_name)));
1432
1433  memset (block, 0, BLOCKSIZE);
1434
1435  /* FIXME: Michael P Urban writes: [a long name file] is being written
1436     when a new volume rolls around [...]  Looks like the wrong value is
1437     being preserved in real_s_name, though.  */
1438
1439  strncpy (block->header.name, real_s_name, NAME_FIELD_SIZE);
1440  block->header.typeflag = GNUTYPE_MULTIVOL;
1441
1442  OFF_TO_CHARS (real_s_sizeleft, block->header.size);
1443  OFF_TO_CHARS (real_s_totsize - real_s_sizeleft,
1444		block->oldgnu_header.offset);
1445
1446  tmp = verbose_option;
1447  verbose_option = 0;
1448  finish_header (&current_stat_info, block, -1);
1449  verbose_option = tmp;
1450  set_next_block_after (block);
1451}
1452
1453/* Add a multi volume header to the current archive. The exact header format
1454   depends on the archive format. */
1455static void
1456add_multi_volume_header (void)
1457{
1458  if (archive_format == POSIX_FORMAT)
1459    {
1460      off_t d = real_s_totsize - real_s_sizeleft;
1461      xheader_store ("GNU.volume.filename", &dummy, real_s_name);
1462      xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
1463      xheader_store ("GNU.volume.offset", &dummy, &d);
1464    }
1465  else
1466    gnu_add_multi_volume_header ();
1467}
1468
1469/* Synchronize multi-volume globals */
1470static void
1471multi_volume_sync ()
1472{
1473  if (multi_volume_option)
1474    {
1475      if (save_name)
1476	{
1477	  assign_string (&real_s_name,
1478			 safer_name_suffix (save_name, false,
1479					    absolute_names_option));
1480	  real_s_totsize = save_totsize;
1481	  real_s_sizeleft = save_sizeleft;
1482	}
1483      else
1484	{
1485	  assign_string (&real_s_name, 0);
1486	  real_s_totsize = 0;
1487	  real_s_sizeleft = 0;
1488	}
1489    }
1490}
1491
1492
1493/* Low-level flush functions */
1494
1495/* Simple flush read (no multi-volume or label extensions) */
1496static void
1497simple_flush_read (void)
1498{
1499  size_t status;		/* result from system call */
1500
1501  do_checkpoint (false);
1502
1503  /* Clear the count of errors.  This only applies to a single call to
1504     flush_read.  */
1505
1506  read_error_count = 0;		/* clear error count */
1507
1508  if (write_archive_to_stdout && record_start_block != 0)
1509    {
1510      archive = STDOUT_FILENO;
1511      status = sys_write_archive_buffer ();
1512      archive = STDIN_FILENO;
1513      if (status != record_size)
1514	archive_write_error (status);
1515    }
1516
1517  for (;;)
1518    {
1519      status = rmtread (archive, record_start->buffer, record_size);
1520      if (status == record_size)
1521	{
1522	  records_read++;
1523	  return;
1524	}
1525      if (status == SAFE_READ_ERROR)
1526	{
1527	  archive_read_error ();
1528	  continue;		/* try again */
1529	}
1530      break;
1531    }
1532  short_read (status);
1533}
1534
1535/* Simple flush write (no multi-volume or label extensions) */
1536static void
1537simple_flush_write (size_t level __attribute__((unused)))
1538{
1539  ssize_t status;
1540
1541  status = _flush_write ();
1542  if (status != record_size)
1543    archive_write_error (status);
1544  else
1545    {
1546      records_written++;
1547      bytes_written += status;
1548    }
1549}
1550
1551
1552/* GNU flush functions. These support multi-volume and archive labels in
1553   GNU and PAX archive formats. */
1554
1555static void
1556_gnu_flush_read (void)
1557{
1558  size_t status;		/* result from system call */
1559
1560  do_checkpoint (false);
1561
1562  /* Clear the count of errors.  This only applies to a single call to
1563     flush_read.  */
1564
1565  read_error_count = 0;		/* clear error count */
1566
1567  if (write_archive_to_stdout && record_start_block != 0)
1568    {
1569      archive = STDOUT_FILENO;
1570      status = sys_write_archive_buffer ();
1571      archive = STDIN_FILENO;
1572      if (status != record_size)
1573	archive_write_error (status);
1574    }
1575
1576  multi_volume_sync ();
1577
1578  for (;;)
1579    {
1580      status = rmtread (archive, record_start->buffer, record_size);
1581      if (status == record_size)
1582	{
1583	  records_read++;
1584	  return;
1585	}
1586
1587      /* The condition below used to include
1588	      || (status > 0 && !read_full_records)
1589	 This is incorrect since even if new_volume() succeeds, the
1590	 subsequent call to rmtread will overwrite the chunk of data
1591	 already read in the buffer, so the processing will fail */
1592      if ((status == 0
1593	   || (status == SAFE_READ_ERROR && errno == ENOSPC))
1594	  && multi_volume_option)
1595	{
1596	  while (!try_new_volume ())
1597	    ;
1598	  return;
1599	}
1600      else if (status == SAFE_READ_ERROR)
1601	{
1602	  archive_read_error ();
1603	  continue;
1604	}
1605      break;
1606    }
1607  short_read (status);
1608}
1609
1610static void
1611gnu_flush_read (void)
1612{
1613  flush_read_ptr = simple_flush_read; /* Avoid recursion */
1614  _gnu_flush_read ();
1615  flush_read_ptr = gnu_flush_read;
1616}
1617
1618static void
1619_gnu_flush_write (size_t buffer_level)
1620{
1621  ssize_t status;
1622  union block *header;
1623  char *copy_ptr;
1624  size_t copy_size;
1625  size_t bufsize;
1626
1627  status = _flush_write ();
1628  if (status != record_size && !multi_volume_option)
1629    archive_write_error (status);
1630  else
1631    {
1632      records_written++;
1633      bytes_written += status;
1634    }
1635
1636  if (status == record_size)
1637    {
1638      multi_volume_sync ();
1639      return;
1640    }
1641
1642  /* In multi-volume mode. */
1643  /* ENXIO is for the UNIX PC.  */
1644  if (status < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
1645    archive_write_error (status);
1646
1647  if (!new_volume (ACCESS_WRITE))
1648    return;
1649
1650  tar_stat_destroy (&dummy);
1651
1652  increase_volume_number ();
1653  prev_written += bytes_written;
1654  bytes_written = 0;
1655
1656  copy_ptr = record_start->buffer + status;
1657  copy_size = buffer_level - status;
1658  /* Switch to the next buffer */
1659  record_index = !record_index;
1660  init_buffer ();
1661
1662  if (volume_label_option)
1663    add_volume_label ();
1664
1665  if (real_s_name)
1666    add_multi_volume_header ();
1667
1668  write_extended (true, &dummy, find_next_block ());
1669  tar_stat_destroy (&dummy);
1670
1671  if (real_s_name)
1672    add_chunk_header ();
1673  header = find_next_block ();
1674  bufsize = available_space_after (header);
1675  while (bufsize < copy_size)
1676    {
1677      memcpy (header->buffer, copy_ptr, bufsize);
1678      copy_ptr += bufsize;
1679      copy_size -= bufsize;
1680      set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
1681      header = find_next_block ();
1682      bufsize = available_space_after (header);
1683    }
1684  memcpy (header->buffer, copy_ptr, copy_size);
1685  memset (header->buffer + copy_size, 0, bufsize - copy_size);
1686  set_next_block_after (header + (copy_size - 1) / BLOCKSIZE);
1687  find_next_block ();
1688}
1689
1690static void
1691gnu_flush_write (size_t buffer_level)
1692{
1693  flush_write_ptr = simple_flush_write; /* Avoid recursion */
1694  _gnu_flush_write (buffer_level);
1695  flush_write_ptr = gnu_flush_write;
1696}
1697
1698void
1699flush_read ()
1700{
1701  flush_read_ptr ();
1702}
1703
1704void
1705flush_write ()
1706{
1707  flush_write_ptr (record_size);
1708}
1709
1710void
1711open_archive (enum access_mode wanted_access)
1712{
1713  flush_read_ptr = gnu_flush_read;
1714  flush_write_ptr = gnu_flush_write;
1715
1716  _open_archive (wanted_access);
1717  switch (wanted_access)
1718    {
1719    case ACCESS_READ:
1720      if (volume_label_option)
1721	match_volume_label ();
1722      break;
1723
1724    case ACCESS_WRITE:
1725      records_written = 0;
1726      if (volume_label_option)
1727	write_volume_label ();
1728      break;
1729
1730    default:
1731      break;
1732    }
1733  set_volume_start_time ();
1734}
1735