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