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