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