]> Dogcows Code - chaz/tar/blob - src/buffer.c
Report record size only if the archive refers to a device.
[chaz/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 bool
683 archive_is_dev ()
684 {
685 struct stat st;
686
687 if (fstat (archive, &st))
688 {
689 stat_diag (*archive_name_cursor);
690 return false;
691 }
692 return S_ISBLK (st.st_mode) || S_ISCHR (st.st_mode);
693 }
694
695 static void
696 short_read (size_t status)
697 {
698 size_t left; /* bytes left */
699 char *more; /* pointer to next byte to read */
700
701 more = record_start->buffer + status;
702 left = record_size - status;
703
704 if (left && left % BLOCKSIZE == 0
705 && verbose_option
706 && record_start_block == 0 && status != 0
707 && archive_is_dev ())
708 {
709 unsigned long rsize = status / BLOCKSIZE;
710 WARN ((0, 0,
711 ngettext ("Record size = %lu block",
712 "Record size = %lu blocks",
713 rsize),
714 rsize));
715 }
716
717 while (left % BLOCKSIZE != 0
718 || (left && status && read_full_records))
719 {
720 if (status)
721 while ((status = rmtread (archive, more, left)) == SAFE_READ_ERROR)
722 archive_read_error ();
723
724 if (status == 0)
725 break;
726
727 if (! read_full_records)
728 {
729 unsigned long rest = record_size - left;
730
731 FATAL_ERROR ((0, 0,
732 ngettext ("Unaligned block (%lu byte) in archive",
733 "Unaligned block (%lu bytes) in archive",
734 rest),
735 rest));
736 }
737
738 left -= status;
739 more += status;
740 }
741
742 record_end = record_start + (record_size - left) / BLOCKSIZE;
743 records_read++;
744 }
745
746 /* Flush the current buffer to/from the archive. */
747 void
748 flush_archive (void)
749 {
750 size_t buffer_level = current_block->buffer - record_start->buffer;
751 record_start_block += record_end - record_start;
752 current_block = record_start;
753 record_end = record_start + blocking_factor;
754
755 if (access_mode == ACCESS_READ && time_to_start_writing)
756 {
757 access_mode = ACCESS_WRITE;
758 time_to_start_writing = false;
759 backspace_output ();
760 }
761
762 switch (access_mode)
763 {
764 case ACCESS_READ:
765 flush_read ();
766 break;
767
768 case ACCESS_WRITE:
769 flush_write_ptr (buffer_level);
770 break;
771
772 case ACCESS_UPDATE:
773 abort ();
774 }
775 }
776
777 /* Backspace the archive descriptor by one record worth. If it's a
778 tape, MTIOCTOP will work. If it's something else, try to seek on
779 it. If we can't seek, we lose! */
780 static void
781 backspace_output (void)
782 {
783 #ifdef MTIOCTOP
784 {
785 struct mtop operation;
786
787 operation.mt_op = MTBSR;
788 operation.mt_count = 1;
789 if (rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0)
790 return;
791 if (errno == EIO && rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0)
792 return;
793 }
794 #endif
795
796 {
797 off_t position = rmtlseek (archive, (off_t) 0, SEEK_CUR);
798
799 /* Seek back to the beginning of this record and start writing there. */
800
801 position -= record_size;
802 if (position < 0)
803 position = 0;
804 if (rmtlseek (archive, position, SEEK_SET) != position)
805 {
806 /* Lseek failed. Try a different method. */
807
808 WARN ((0, 0,
809 _("Cannot backspace archive file; it may be unreadable without -i")));
810
811 /* Replace the first part of the record with NULs. */
812
813 if (record_start->buffer != output_start)
814 memset (record_start->buffer, 0,
815 output_start - record_start->buffer);
816 }
817 }
818 }
819
820 off_t
821 seek_archive (off_t size)
822 {
823 off_t start = current_block_ordinal ();
824 off_t offset;
825 off_t nrec, nblk;
826 off_t skipped = (blocking_factor - (current_block - record_start));
827
828 size -= skipped * BLOCKSIZE;
829
830 if (size < record_size)
831 return 0;
832 /* FIXME: flush? */
833
834 /* Compute number of records to skip */
835 nrec = size / record_size;
836 offset = rmtlseek (archive, nrec * record_size, SEEK_CUR);
837 if (offset < 0)
838 return offset;
839
840 if (offset % record_size)
841 FATAL_ERROR ((0, 0, _("rmtlseek not stopped at a record boundary")));
842
843 /* Convert to number of records */
844 offset /= BLOCKSIZE;
845 /* Compute number of skipped blocks */
846 nblk = offset - start;
847
848 /* Update buffering info */
849 records_read += nblk / blocking_factor;
850 record_start_block = offset - blocking_factor;
851 current_block = record_end;
852
853 return nblk;
854 }
855
856 /* Close the archive file. */
857 void
858 close_archive (void)
859 {
860 if (time_to_start_writing || access_mode == ACCESS_WRITE)
861 {
862 flush_archive ();
863 if (current_block > record_start)
864 flush_archive ();
865 }
866
867 compute_duration ();
868 if (verify_option)
869 verify_volume ();
870
871 if (rmtclose (archive) != 0)
872 close_error (*archive_name_cursor);
873
874 sys_wait_for_child (child_pid, hit_eof);
875
876 tar_stat_destroy (&current_stat_info);
877 if (save_name)
878 free (save_name);
879 if (real_s_name)
880 free (real_s_name);
881 free (record_buffer[0]);
882 free (record_buffer[1]);
883 }
884
885 /* Called to initialize the global volume number. */
886 void
887 init_volume_number (void)
888 {
889 FILE *file = fopen (volno_file_option, "r");
890
891 if (file)
892 {
893 if (fscanf (file, "%d", &global_volno) != 1
894 || global_volno < 0)
895 FATAL_ERROR ((0, 0, _("%s: contains invalid volume number"),
896 quotearg_colon (volno_file_option)));
897 if (ferror (file))
898 read_error (volno_file_option);
899 if (fclose (file) != 0)
900 close_error (volno_file_option);
901 }
902 else if (errno != ENOENT)
903 open_error (volno_file_option);
904 }
905
906 /* Called to write out the closing global volume number. */
907 void
908 closeout_volume_number (void)
909 {
910 FILE *file = fopen (volno_file_option, "w");
911
912 if (file)
913 {
914 fprintf (file, "%d\n", global_volno);
915 if (ferror (file))
916 write_error (volno_file_option);
917 if (fclose (file) != 0)
918 close_error (volno_file_option);
919 }
920 else
921 open_error (volno_file_option);
922 }
923
924 \f
925 static void
926 increase_volume_number ()
927 {
928 global_volno++;
929 if (global_volno < 0)
930 FATAL_ERROR ((0, 0, _("Volume number overflow")));
931 volno++;
932 }
933
934 void
935 change_tape_menu (FILE *read_file)
936 {
937 char *input_buffer = NULL;
938 size_t size = 0;
939 bool stop = false;
940
941 while (!stop)
942 {
943 fputc ('\007', stderr);
944 fprintf (stderr,
945 _("Prepare volume #%d for %s and hit return: "),
946 global_volno + 1, quote (*archive_name_cursor));
947 fflush (stderr);
948
949 if (getline (&input_buffer, &size, read_file) <= 0)
950 {
951 WARN ((0, 0, _("EOF where user reply was expected")));
952
953 if (subcommand_option != EXTRACT_SUBCOMMAND
954 && subcommand_option != LIST_SUBCOMMAND
955 && subcommand_option != DIFF_SUBCOMMAND)
956 WARN ((0, 0, _("WARNING: Archive is incomplete")));
957
958 fatal_exit ();
959 }
960
961 if (input_buffer[0] == '\n'
962 || input_buffer[0] == 'y'
963 || input_buffer[0] == 'Y')
964 break;
965
966 switch (input_buffer[0])
967 {
968 case '?':
969 {
970 fprintf (stderr, _("\
971 n name Give a new file name for the next (and subsequent) volume(s)\n\
972 q Abort tar\n\
973 y or newline Continue operation\n"));
974 if (!restrict_option)
975 fprintf (stderr, _(" ! Spawn a subshell\n"));
976 fprintf (stderr, _(" ? Print this list\n"));
977 }
978 break;
979
980 case 'q':
981 /* Quit. */
982
983 WARN ((0, 0, _("No new volume; exiting.\n")));
984
985 if (subcommand_option != EXTRACT_SUBCOMMAND
986 && subcommand_option != LIST_SUBCOMMAND
987 && subcommand_option != DIFF_SUBCOMMAND)
988 WARN ((0, 0, _("WARNING: Archive is incomplete")));
989
990 fatal_exit ();
991
992 case 'n':
993 /* Get new file name. */
994
995 {
996 char *name;
997 char *cursor;
998
999 for (name = input_buffer + 1;
1000 *name == ' ' || *name == '\t';
1001 name++)
1002 ;
1003
1004 for (cursor = name; *cursor && *cursor != '\n'; cursor++)
1005 ;
1006 *cursor = '\0';
1007
1008 if (name[0])
1009 {
1010 /* FIXME: the following allocation is never reclaimed. */
1011 *archive_name_cursor = xstrdup (name);
1012 stop = true;
1013 }
1014 else
1015 fprintf (stderr, "%s",
1016 _("File name not specified. Try again.\n"));
1017 }
1018 break;
1019
1020 case '!':
1021 if (!restrict_option)
1022 {
1023 sys_spawn_shell ();
1024 break;
1025 }
1026 /* FALL THROUGH */
1027
1028 default:
1029 fprintf (stderr, _("Invalid input. Type ? for help.\n"));
1030 }
1031 }
1032 free (input_buffer);
1033 }
1034
1035 /* We've hit the end of the old volume. Close it and open the next one.
1036 Return nonzero on success.
1037 */
1038 static bool
1039 new_volume (enum access_mode mode)
1040 {
1041 static FILE *read_file;
1042 static int looped;
1043 int prompt;
1044
1045 if (!read_file && !info_script_option)
1046 /* FIXME: if fopen is used, it will never be closed. */
1047 read_file = archive == STDIN_FILENO ? fopen (TTY_NAME, "r") : stdin;
1048
1049 if (now_verifying)
1050 return false;
1051 if (verify_option)
1052 verify_volume ();
1053
1054 assign_string (&volume_label, NULL);
1055 assign_string (&continued_file_name, NULL);
1056 continued_file_size = continued_file_offset = 0;
1057 current_block = record_start;
1058
1059 if (rmtclose (archive) != 0)
1060 close_error (*archive_name_cursor);
1061
1062 archive_name_cursor++;
1063 if (archive_name_cursor == archive_name_array + archive_names)
1064 {
1065 archive_name_cursor = archive_name_array;
1066 looped = 1;
1067 }
1068 prompt = looped;
1069
1070 tryagain:
1071 if (prompt)
1072 {
1073 /* We have to prompt from now on. */
1074
1075 if (info_script_option)
1076 {
1077 if (volno_file_option)
1078 closeout_volume_number ();
1079 if (sys_exec_info_script (archive_name_cursor, global_volno+1))
1080 FATAL_ERROR ((0, 0, _("%s command failed"),
1081 quote (info_script_option)));
1082 }
1083 else
1084 change_tape_menu (read_file);
1085 }
1086
1087 if (strcmp (archive_name_cursor[0], "-") == 0)
1088 {
1089 read_full_records = true;
1090 archive = STDIN_FILENO;
1091 }
1092 else if (verify_option)
1093 archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
1094 rsh_command_option);
1095 else
1096 switch (mode)
1097 {
1098 case ACCESS_READ:
1099 archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW,
1100 rsh_command_option);
1101 break;
1102
1103 case ACCESS_WRITE:
1104 if (backup_option)
1105 maybe_backup_file (*archive_name_cursor, 1);
1106 archive = rmtcreat (*archive_name_cursor, MODE_RW,
1107 rsh_command_option);
1108 break;
1109
1110 case ACCESS_UPDATE:
1111 archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
1112 rsh_command_option);
1113 break;
1114 }
1115
1116 if (archive < 0)
1117 {
1118 open_warn (*archive_name_cursor);
1119 if (!verify_option && mode == ACCESS_WRITE && backup_option)
1120 undo_last_backup ();
1121 prompt = 1;
1122 goto tryagain;
1123 }
1124
1125 SET_BINARY_MODE (archive);
1126
1127 return true;
1128 }
1129
1130 static bool
1131 read_header0 (struct tar_stat_info *info)
1132 {
1133 enum read_header rc;
1134
1135 tar_stat_init (info);
1136 rc = read_header_primitive (false, info);
1137 if (rc == HEADER_SUCCESS)
1138 {
1139 set_next_block_after (current_header);
1140 return true;
1141 }
1142 ERROR ((0, 0, _("This does not look like a tar archive")));
1143 return false;
1144 }
1145
1146 bool
1147 try_new_volume ()
1148 {
1149 size_t status;
1150 union block *header;
1151 enum access_mode acc;
1152
1153 switch (subcommand_option)
1154 {
1155 case APPEND_SUBCOMMAND:
1156 case CAT_SUBCOMMAND:
1157 case UPDATE_SUBCOMMAND:
1158 acc = ACCESS_UPDATE;
1159 break;
1160
1161 default:
1162 acc = ACCESS_READ;
1163 break;
1164 }
1165
1166 if (!new_volume (acc))
1167 return true;
1168
1169 while ((status = rmtread (archive, record_start->buffer, record_size))
1170 == SAFE_READ_ERROR)
1171 archive_read_error ();
1172
1173 if (status != record_size)
1174 short_read (status);
1175
1176 header = find_next_block ();
1177 if (!header)
1178 return false;
1179
1180 switch (header->header.typeflag)
1181 {
1182 case XGLTYPE:
1183 {
1184 if (!read_header0 (&dummy))
1185 return false;
1186 xheader_decode (&dummy); /* decodes values from the global header */
1187 tar_stat_destroy (&dummy);
1188 if (!real_s_name)
1189 {
1190 /* We have read the extended header of the first member in
1191 this volume. Put it back, so next read_header works as
1192 expected. */
1193 current_block = record_start;
1194 }
1195 break;
1196 }
1197
1198 case GNUTYPE_VOLHDR:
1199 if (!read_header0 (&dummy))
1200 return false;
1201 tar_stat_destroy (&dummy);
1202 assign_string (&volume_label, current_header->header.name);
1203 set_next_block_after (header);
1204 header = find_next_block ();
1205 if (header->header.typeflag != GNUTYPE_MULTIVOL)
1206 break;
1207 /* FALL THROUGH */
1208
1209 case GNUTYPE_MULTIVOL:
1210 if (!read_header0 (&dummy))
1211 return false;
1212 tar_stat_destroy (&dummy);
1213 assign_string (&continued_file_name, current_header->header.name);
1214 continued_file_size =
1215 UINTMAX_FROM_HEADER (current_header->header.size);
1216 continued_file_offset =
1217 UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset);
1218 break;
1219
1220 default:
1221 break;
1222 }
1223
1224 if (real_s_name)
1225 {
1226 uintmax_t s;
1227 if (!continued_file_name
1228 || strcmp (continued_file_name, real_s_name))
1229 {
1230 if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
1231 && strlen (real_s_name) >= NAME_FIELD_SIZE
1232 && strncmp (continued_file_name, real_s_name,
1233 NAME_FIELD_SIZE) == 0)
1234 WARN ((0, 0,
1235 _("%s is possibly continued on this volume: header contains truncated name"),
1236 quote (real_s_name)));
1237 else
1238 {
1239 WARN ((0, 0, _("%s is not continued on this volume"),
1240 quote (real_s_name)));
1241 return false;
1242 }
1243 }
1244
1245 s = continued_file_size + continued_file_offset;
1246
1247 if (real_s_totsize != s || s < 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, _("%s is the wrong size (%s != %s + %s)"),
1254 quote (continued_file_name),
1255 STRINGIFY_BIGINT (save_totsize, totsizebuf),
1256 STRINGIFY_BIGINT (continued_file_size, s1buf),
1257 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
1258 return false;
1259 }
1260
1261 if (real_s_totsize - real_s_sizeleft != continued_file_offset)
1262 {
1263 char totsizebuf[UINTMAX_STRSIZE_BOUND];
1264 char s1buf[UINTMAX_STRSIZE_BOUND];
1265 char s2buf[UINTMAX_STRSIZE_BOUND];
1266
1267 WARN ((0, 0, _("This volume is out of sequence (%s - %s != %s)"),
1268 STRINGIFY_BIGINT (real_s_totsize, totsizebuf),
1269 STRINGIFY_BIGINT (real_s_sizeleft, s1buf),
1270 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
1271
1272 return false;
1273 }
1274 }
1275
1276 increase_volume_number ();
1277 return true;
1278 }
1279
1280 \f
1281 /* Check the LABEL block against the volume label, seen as a globbing
1282 pattern. Return true if the pattern matches. In case of failure,
1283 retry matching a volume sequence number before giving up in
1284 multi-volume mode. */
1285 static bool
1286 check_label_pattern (union block *label)
1287 {
1288 char *string;
1289 bool result;
1290
1291 if (! memchr (label->header.name, '\0', sizeof label->header.name))
1292 return false;
1293
1294 if (fnmatch (volume_label_option, label->header.name, 0) == 0)
1295 return true;
1296
1297 if (!multi_volume_option)
1298 return false;
1299
1300 string = xmalloc (strlen (volume_label_option)
1301 + sizeof VOLUME_LABEL_APPEND + 1);
1302 strcpy (string, volume_label_option);
1303 strcat (string, VOLUME_LABEL_APPEND);
1304 result = fnmatch (string, label->header.name, 0) == 0;
1305 free (string);
1306 return result;
1307 }
1308
1309 /* Check if the next block contains a volume label and if this matches
1310 the one given in the command line */
1311 static void
1312 match_volume_label (void)
1313 {
1314 union block *label = find_next_block ();
1315
1316 if (!label)
1317 FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
1318 quote (volume_label_option)));
1319 if (!check_label_pattern (label))
1320 FATAL_ERROR ((0, 0, _("Volume %s does not match %s"),
1321 quote_n (0, label->header.name),
1322 quote_n (1, volume_label_option)));
1323 }
1324
1325 /* Mark the archive with volume label STR. */
1326 static void
1327 _write_volume_label (const char *str)
1328 {
1329 if (archive_format == POSIX_FORMAT)
1330 xheader_store ("GNU.volume.label", &dummy, str);
1331 else
1332 {
1333 union block *label = find_next_block ();
1334
1335 memset (label, 0, BLOCKSIZE);
1336
1337 strcpy (label->header.name, str);
1338 assign_string (&current_stat_info.file_name,
1339 label->header.name);
1340 current_stat_info.had_trailing_slash =
1341 strip_trailing_slashes (current_stat_info.file_name);
1342
1343 label->header.typeflag = GNUTYPE_VOLHDR;
1344 TIME_TO_CHARS (start_time.tv_sec, label->header.mtime);
1345 finish_header (&current_stat_info, label, -1);
1346 set_next_block_after (label);
1347 }
1348 }
1349
1350 #define VOL_SUFFIX "Volume"
1351
1352 /* Add a volume label to a part of multi-volume archive */
1353 static void
1354 add_volume_label (void)
1355 {
1356 char buf[UINTMAX_STRSIZE_BOUND];
1357 char *p = STRINGIFY_BIGINT (volno, buf);
1358 char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX
1359 + strlen (p) + 2);
1360 sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p);
1361 _write_volume_label (s);
1362 free (s);
1363 }
1364
1365 static void
1366 add_chunk_header ()
1367 {
1368 if (archive_format == POSIX_FORMAT)
1369 {
1370 off_t block_ordinal;
1371 union block *blk;
1372 struct tar_stat_info st;
1373 static size_t real_s_part_no; /* FIXME */
1374
1375 real_s_part_no++;
1376 memset (&st, 0, sizeof st);
1377 st.orig_file_name = st.file_name = real_s_name;
1378 st.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
1379 st.stat.st_uid = getuid ();
1380 st.stat.st_gid = getgid ();
1381 st.orig_file_name = xheader_format_name (&st,
1382 "%d/GNUFileParts.%p/%f.%n",
1383 real_s_part_no);
1384 st.file_name = st.orig_file_name;
1385 st.archive_file_size = st.stat.st_size = real_s_sizeleft;
1386
1387 block_ordinal = current_block_ordinal ();
1388 blk = start_header (&st);
1389 if (!blk)
1390 abort (); /* FIXME */
1391 finish_header (&st, blk, block_ordinal);
1392 free (st.orig_file_name);
1393 }
1394 }
1395
1396
1397 /* Add a volume label to the current archive */
1398 static void
1399 write_volume_label (void)
1400 {
1401 if (multi_volume_option)
1402 add_volume_label ();
1403 else
1404 _write_volume_label (volume_label_option);
1405 }
1406
1407 /* Write GNU multi-volume header */
1408 static void
1409 gnu_add_multi_volume_header (void)
1410 {
1411 int tmp;
1412 union block *block = find_next_block ();
1413
1414 if (strlen (real_s_name) > NAME_FIELD_SIZE)
1415 WARN ((0, 0,
1416 _("%s: file name too long to be stored in a GNU multivolume header, truncated"),
1417 quotearg_colon (real_s_name)));
1418
1419 memset (block, 0, BLOCKSIZE);
1420
1421 /* FIXME: Michael P Urban writes: [a long name file] is being written
1422 when a new volume rolls around [...] Looks like the wrong value is
1423 being preserved in real_s_name, though. */
1424
1425 strncpy (block->header.name, real_s_name, NAME_FIELD_SIZE);
1426 block->header.typeflag = GNUTYPE_MULTIVOL;
1427
1428 OFF_TO_CHARS (real_s_sizeleft, block->header.size);
1429 OFF_TO_CHARS (real_s_totsize - real_s_sizeleft,
1430 block->oldgnu_header.offset);
1431
1432 tmp = verbose_option;
1433 verbose_option = 0;
1434 finish_header (&current_stat_info, block, -1);
1435 verbose_option = tmp;
1436 set_next_block_after (block);
1437 }
1438
1439 /* Add a multi volume header to the current archive. The exact header format
1440 depends on the archive format. */
1441 static void
1442 add_multi_volume_header (void)
1443 {
1444 if (archive_format == POSIX_FORMAT)
1445 {
1446 off_t d = real_s_totsize - real_s_sizeleft;
1447 xheader_store ("GNU.volume.filename", &dummy, real_s_name);
1448 xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
1449 xheader_store ("GNU.volume.offset", &dummy, &d);
1450 }
1451 else
1452 gnu_add_multi_volume_header ();
1453 }
1454
1455 /* Synchronize multi-volume globals */
1456 static void
1457 multi_volume_sync ()
1458 {
1459 if (multi_volume_option)
1460 {
1461 if (save_name)
1462 {
1463 assign_string (&real_s_name,
1464 safer_name_suffix (save_name, false,
1465 absolute_names_option));
1466 real_s_totsize = save_totsize;
1467 real_s_sizeleft = save_sizeleft;
1468 }
1469 else
1470 {
1471 assign_string (&real_s_name, 0);
1472 real_s_totsize = 0;
1473 real_s_sizeleft = 0;
1474 }
1475 }
1476 }
1477
1478 \f
1479 /* Low-level flush functions */
1480
1481 /* Simple flush read (no multi-volume or label extensions) */
1482 static void
1483 simple_flush_read (void)
1484 {
1485 size_t status; /* result from system call */
1486
1487 checkpoint_run (false);
1488
1489 /* Clear the count of errors. This only applies to a single call to
1490 flush_read. */
1491
1492 read_error_count = 0; /* clear error count */
1493
1494 if (write_archive_to_stdout && record_start_block != 0)
1495 {
1496 archive = STDOUT_FILENO;
1497 status = sys_write_archive_buffer ();
1498 archive = STDIN_FILENO;
1499 if (status != record_size)
1500 archive_write_error (status);
1501 }
1502
1503 for (;;)
1504 {
1505 status = rmtread (archive, record_start->buffer, record_size);
1506 if (status == record_size)
1507 {
1508 records_read++;
1509 return;
1510 }
1511 if (status == SAFE_READ_ERROR)
1512 {
1513 archive_read_error ();
1514 continue; /* try again */
1515 }
1516 break;
1517 }
1518 short_read (status);
1519 }
1520
1521 /* Simple flush write (no multi-volume or label extensions) */
1522 static void
1523 simple_flush_write (size_t level __attribute__((unused)))
1524 {
1525 ssize_t status;
1526
1527 status = _flush_write ();
1528 if (status != record_size)
1529 archive_write_error (status);
1530 else
1531 {
1532 records_written++;
1533 bytes_written += status;
1534 }
1535 }
1536
1537 \f
1538 /* GNU flush functions. These support multi-volume and archive labels in
1539 GNU and PAX archive formats. */
1540
1541 static void
1542 _gnu_flush_read (void)
1543 {
1544 size_t status; /* result from system call */
1545
1546 checkpoint_run (false);
1547
1548 /* Clear the count of errors. This only applies to a single call to
1549 flush_read. */
1550
1551 read_error_count = 0; /* clear error count */
1552
1553 if (write_archive_to_stdout && record_start_block != 0)
1554 {
1555 archive = STDOUT_FILENO;
1556 status = sys_write_archive_buffer ();
1557 archive = STDIN_FILENO;
1558 if (status != record_size)
1559 archive_write_error (status);
1560 }
1561
1562 multi_volume_sync ();
1563
1564 for (;;)
1565 {
1566 status = rmtread (archive, record_start->buffer, record_size);
1567 if (status == record_size)
1568 {
1569 records_read++;
1570 return;
1571 }
1572
1573 /* The condition below used to include
1574 || (status > 0 && !read_full_records)
1575 This is incorrect since even if new_volume() succeeds, the
1576 subsequent call to rmtread will overwrite the chunk of data
1577 already read in the buffer, so the processing will fail */
1578 if ((status == 0
1579 || (status == SAFE_READ_ERROR && errno == ENOSPC))
1580 && multi_volume_option)
1581 {
1582 while (!try_new_volume ())
1583 ;
1584 if (current_block == record_end)
1585 /* Necessary for blocking_factor == 1 */
1586 flush_archive();
1587 return;
1588 }
1589 else if (status == SAFE_READ_ERROR)
1590 {
1591 archive_read_error ();
1592 continue;
1593 }
1594 break;
1595 }
1596 short_read (status);
1597 }
1598
1599 static void
1600 gnu_flush_read (void)
1601 {
1602 flush_read_ptr = simple_flush_read; /* Avoid recursion */
1603 _gnu_flush_read ();
1604 flush_read_ptr = gnu_flush_read;
1605 }
1606
1607 static void
1608 _gnu_flush_write (size_t buffer_level)
1609 {
1610 ssize_t status;
1611 union block *header;
1612 char *copy_ptr;
1613 size_t copy_size;
1614 size_t bufsize;
1615 tarlong wrt;
1616
1617 status = _flush_write ();
1618 if (status != record_size && !multi_volume_option)
1619 archive_write_error (status);
1620 else
1621 {
1622 if (status)
1623 records_written++;
1624 bytes_written += status;
1625 }
1626
1627 if (status == record_size)
1628 {
1629 multi_volume_sync ();
1630 return;
1631 }
1632
1633 if (status % BLOCKSIZE)
1634 {
1635 ERROR ((0, 0, _("write did not end on a block boundary")));
1636 archive_write_error (status);
1637 }
1638
1639 /* In multi-volume mode. */
1640 /* ENXIO is for the UNIX PC. */
1641 if (status < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
1642 archive_write_error (status);
1643
1644 real_s_sizeleft -= status;
1645 if (!new_volume (ACCESS_WRITE))
1646 return;
1647
1648 tar_stat_destroy (&dummy);
1649
1650 increase_volume_number ();
1651 prev_written += bytes_written;
1652 bytes_written = 0;
1653
1654 copy_ptr = record_start->buffer + status;
1655 copy_size = buffer_level - status;
1656
1657 /* Switch to the next buffer */
1658 record_index = !record_index;
1659 init_buffer ();
1660
1661 if (volume_label_option)
1662 add_volume_label ();
1663
1664 if (real_s_name)
1665 add_multi_volume_header ();
1666
1667 write_extended (true, &dummy, find_next_block ());
1668 tar_stat_destroy (&dummy);
1669
1670 if (real_s_name)
1671 add_chunk_header ();
1672 wrt = bytes_written;
1673 header = find_next_block ();
1674 bufsize = available_space_after (header);
1675 while (bufsize < copy_size)
1676 {
1677 memcpy (header->buffer, copy_ptr, bufsize);
1678 copy_ptr += bufsize;
1679 copy_size -= bufsize;
1680 set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
1681 header = find_next_block ();
1682 bufsize = available_space_after (header);
1683 }
1684 memcpy (header->buffer, copy_ptr, copy_size);
1685 memset (header->buffer + copy_size, 0, bufsize - copy_size);
1686 set_next_block_after (header + (copy_size - 1) / BLOCKSIZE);
1687 if (multi_volume_option && wrt < bytes_written)
1688 {
1689 /* The value of bytes_written has changed while moving data;
1690 that means that flush_archive was executed at least once in
1691 between, and, as a consequence, copy_size bytes were not written
1692 to disk. We need to update sizeleft variables to compensate for
1693 that. */
1694 save_sizeleft += copy_size;
1695 multi_volume_sync ();
1696 }
1697 find_next_block ();
1698 }
1699
1700 static void
1701 gnu_flush_write (size_t buffer_level)
1702 {
1703 flush_write_ptr = simple_flush_write; /* Avoid recursion */
1704 _gnu_flush_write (buffer_level);
1705 flush_write_ptr = gnu_flush_write;
1706 }
1707
1708 void
1709 flush_read ()
1710 {
1711 flush_read_ptr ();
1712 }
1713
1714 void
1715 flush_write ()
1716 {
1717 flush_write_ptr (record_size);
1718 }
1719
1720 void
1721 open_archive (enum access_mode wanted_access)
1722 {
1723 flush_read_ptr = gnu_flush_read;
1724 flush_write_ptr = gnu_flush_write;
1725
1726 _open_archive (wanted_access);
1727 switch (wanted_access)
1728 {
1729 case ACCESS_READ:
1730 if (volume_label_option)
1731 match_volume_label ();
1732 break;
1733
1734 case ACCESS_WRITE:
1735 records_written = 0;
1736 if (volume_label_option)
1737 write_volume_label ();
1738 break;
1739
1740 default:
1741 break;
1742 }
1743 set_volume_start_time ();
1744 }
This page took 0.104722 seconds and 5 git commands to generate.