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