]> Dogcows Code - chaz/tar/blob - src/buffer.c
Bugfix
[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 * BLOCKSIZE;
859
860 if (size <= skipped)
861 return 0;
862
863 /* Compute number of records to skip */
864 nrec = (size - skipped) / record_size;
865 if (nrec == 0)
866 return 0;
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, read_header_auto);
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 tar_stat_init (&dummy);
1217 if (read_header (&header, &dummy, read_header_x_global)
1218 != HEADER_SUCCESS_EXTENDED)
1219 {
1220 ERROR ((0, 0, _("This does not look like a tar archive")));
1221 return false;
1222 }
1223
1224 xheader_decode (&dummy); /* decodes values from the global header */
1225 tar_stat_destroy (&dummy);
1226
1227 /* The initial global header must be immediately followed by
1228 an extended PAX header for the first member in this volume.
1229 However, in some cases tar may split volumes in the middle
1230 of a PAX header. This is incorrect, and should be fixed
1231 in the future versions. In the meantime we must be
1232 prepared to correctly list and extract such archives.
1233
1234 If this happens, the following call to read_header returns
1235 HEADER_FAILURE, which is ignored.
1236
1237 See also tests/multiv07.at */
1238
1239 switch (read_header (&header, &dummy, read_header_auto))
1240 {
1241 case HEADER_SUCCESS:
1242 set_next_block_after (header);
1243 break;
1244
1245 case HEADER_FAILURE:
1246 break;
1247
1248 default:
1249 ERROR ((0, 0, _("This does not look like a tar archive")));
1250 return false;
1251 }
1252 break;
1253 }
1254
1255 case GNUTYPE_VOLHDR:
1256 if (!read_header0 (&dummy))
1257 return false;
1258 tar_stat_destroy (&dummy);
1259 assign_string (&volume_label, current_header->header.name);
1260 set_next_block_after (header);
1261 header = find_next_block ();
1262 if (header->header.typeflag != GNUTYPE_MULTIVOL)
1263 break;
1264 /* FALL THROUGH */
1265
1266 case GNUTYPE_MULTIVOL:
1267 if (!read_header0 (&dummy))
1268 return false;
1269 tar_stat_destroy (&dummy);
1270 assign_string (&continued_file_name, current_header->header.name);
1271 continued_file_size =
1272 UINTMAX_FROM_HEADER (current_header->header.size);
1273 continued_file_offset =
1274 UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset);
1275 break;
1276
1277 default:
1278 break;
1279 }
1280
1281 if (real_s_name)
1282 {
1283 uintmax_t s;
1284 if (!continued_file_name
1285 || strcmp (continued_file_name, real_s_name))
1286 {
1287 if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
1288 && strlen (real_s_name) >= NAME_FIELD_SIZE
1289 && strncmp (continued_file_name, real_s_name,
1290 NAME_FIELD_SIZE) == 0)
1291 WARN ((0, 0,
1292 _("%s is possibly continued on this volume: header contains truncated name"),
1293 quote (real_s_name)));
1294 else
1295 {
1296 WARN ((0, 0, _("%s is not continued on this volume"),
1297 quote (real_s_name)));
1298 return false;
1299 }
1300 }
1301
1302 s = continued_file_size + continued_file_offset;
1303
1304 if (real_s_totsize != s || s < continued_file_offset)
1305 {
1306 char totsizebuf[UINTMAX_STRSIZE_BOUND];
1307 char s1buf[UINTMAX_STRSIZE_BOUND];
1308 char s2buf[UINTMAX_STRSIZE_BOUND];
1309
1310 WARN ((0, 0, _("%s is the wrong size (%s != %s + %s)"),
1311 quote (continued_file_name),
1312 STRINGIFY_BIGINT (save_totsize, totsizebuf),
1313 STRINGIFY_BIGINT (continued_file_size, s1buf),
1314 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
1315 return false;
1316 }
1317
1318 if (real_s_totsize - real_s_sizeleft != continued_file_offset)
1319 {
1320 char totsizebuf[UINTMAX_STRSIZE_BOUND];
1321 char s1buf[UINTMAX_STRSIZE_BOUND];
1322 char s2buf[UINTMAX_STRSIZE_BOUND];
1323
1324 WARN ((0, 0, _("This volume is out of sequence (%s - %s != %s)"),
1325 STRINGIFY_BIGINT (real_s_totsize, totsizebuf),
1326 STRINGIFY_BIGINT (real_s_sizeleft, s1buf),
1327 STRINGIFY_BIGINT (continued_file_offset, s2buf)));
1328
1329 return false;
1330 }
1331 }
1332
1333 increase_volume_number ();
1334 return true;
1335 }
1336
1337 \f
1338 #define VOLUME_TEXT " Volume "
1339 #define VOLUME_TEXT_LEN (sizeof VOLUME_TEXT - 1)
1340
1341 char *
1342 drop_volume_label_suffix (const char *label)
1343 {
1344 const char *p;
1345 size_t len = strlen (label);
1346
1347 if (len < 1)
1348 return NULL;
1349
1350 for (p = label + len - 1; p > label && isdigit ((unsigned char) *p); p--)
1351 ;
1352 if (p > label && p - (VOLUME_TEXT_LEN - 1) > label)
1353 {
1354 p -= VOLUME_TEXT_LEN - 1;
1355 if (memcmp (p, VOLUME_TEXT, VOLUME_TEXT_LEN) == 0)
1356 {
1357 char *s = xmalloc ((len = p - label) + 1);
1358 memcpy (s, label, len);
1359 s[len] = 0;
1360 return s;
1361 }
1362 }
1363
1364 return NULL;
1365 }
1366
1367 /* Check LABEL against the volume label, seen as a globbing
1368 pattern. Return true if the pattern matches. In case of failure,
1369 retry matching a volume sequence number before giving up in
1370 multi-volume mode. */
1371 static bool
1372 check_label_pattern (const char *label)
1373 {
1374 char *string;
1375 bool result;
1376
1377 if (fnmatch (volume_label_option, label, 0) == 0)
1378 return true;
1379
1380 if (!multi_volume_option)
1381 return false;
1382
1383 string = drop_volume_label_suffix (label);
1384 if (string)
1385 {
1386 result = fnmatch (string, volume_label_option, 0) == 0;
1387 free (string);
1388 }
1389 return result;
1390 }
1391
1392 /* Check if the next block contains a volume label and if this matches
1393 the one given in the command line */
1394 static void
1395 match_volume_label (void)
1396 {
1397 if (!volume_label)
1398 {
1399 union block *label = find_next_block ();
1400
1401 if (!label)
1402 FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
1403 quote (volume_label_option)));
1404 if (label->header.typeflag == GNUTYPE_VOLHDR)
1405 {
1406 if (memchr (label->header.name, '\0', sizeof label->header.name))
1407 assign_string (&volume_label, label->header.name);
1408 else
1409 {
1410 volume_label = xmalloc (sizeof (label->header.name) + 1);
1411 memcpy (volume_label, label->header.name,
1412 sizeof (label->header.name));
1413 volume_label[sizeof (label->header.name)] = 0;
1414 }
1415 }
1416 else if (label->header.typeflag == XGLTYPE)
1417 {
1418 struct tar_stat_info st;
1419 tar_stat_init (&st);
1420 xheader_read (&st.xhdr, label,
1421 OFF_FROM_HEADER (label->header.size));
1422 xheader_decode (&st);
1423 tar_stat_destroy (&st);
1424 }
1425 }
1426
1427 if (!volume_label)
1428 FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
1429 quote (volume_label_option)));
1430
1431 if (!check_label_pattern (volume_label))
1432 FATAL_ERROR ((0, 0, _("Volume %s does not match %s"),
1433 quote_n (0, volume_label),
1434 quote_n (1, volume_label_option)));
1435 }
1436
1437 /* Mark the archive with volume label STR. */
1438 static void
1439 _write_volume_label (const char *str)
1440 {
1441 if (archive_format == POSIX_FORMAT)
1442 xheader_store ("GNU.volume.label", &dummy, str);
1443 else
1444 {
1445 union block *label = find_next_block ();
1446
1447 memset (label, 0, BLOCKSIZE);
1448
1449 strcpy (label->header.name, str);
1450 assign_string (&current_stat_info.file_name,
1451 label->header.name);
1452 current_stat_info.had_trailing_slash =
1453 strip_trailing_slashes (current_stat_info.file_name);
1454
1455 label->header.typeflag = GNUTYPE_VOLHDR;
1456 TIME_TO_CHARS (start_time.tv_sec, label->header.mtime);
1457 finish_header (&current_stat_info, label, -1);
1458 set_next_block_after (label);
1459 }
1460 }
1461
1462 #define VOL_SUFFIX "Volume"
1463
1464 /* Add a volume label to a part of multi-volume archive */
1465 static void
1466 add_volume_label (void)
1467 {
1468 char buf[UINTMAX_STRSIZE_BOUND];
1469 char *p = STRINGIFY_BIGINT (volno, buf);
1470 char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX
1471 + strlen (p) + 2);
1472 sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p);
1473 _write_volume_label (s);
1474 free (s);
1475 }
1476
1477 static void
1478 add_chunk_header ()
1479 {
1480 if (archive_format == POSIX_FORMAT)
1481 {
1482 off_t block_ordinal;
1483 union block *blk;
1484 struct tar_stat_info st;
1485 static size_t real_s_part_no; /* FIXME */
1486
1487 real_s_part_no++;
1488 memset (&st, 0, sizeof st);
1489 st.orig_file_name = st.file_name = real_s_name;
1490 st.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
1491 st.stat.st_uid = getuid ();
1492 st.stat.st_gid = getgid ();
1493 st.orig_file_name = xheader_format_name (&st,
1494 "%d/GNUFileParts.%p/%f.%n",
1495 real_s_part_no);
1496 st.file_name = st.orig_file_name;
1497 st.archive_file_size = st.stat.st_size = real_s_sizeleft;
1498
1499 block_ordinal = current_block_ordinal ();
1500 blk = start_header (&st);
1501 if (!blk)
1502 abort (); /* FIXME */
1503 finish_header (&st, blk, block_ordinal);
1504 free (st.orig_file_name);
1505 }
1506 }
1507
1508
1509 /* Add a volume label to the current archive */
1510 static void
1511 write_volume_label (void)
1512 {
1513 if (multi_volume_option)
1514 add_volume_label ();
1515 else
1516 _write_volume_label (volume_label_option);
1517 }
1518
1519 /* Write GNU multi-volume header */
1520 static void
1521 gnu_add_multi_volume_header (void)
1522 {
1523 int tmp;
1524 union block *block = find_next_block ();
1525
1526 if (strlen (real_s_name) > NAME_FIELD_SIZE)
1527 WARN ((0, 0,
1528 _("%s: file name too long to be stored in a GNU multivolume header, truncated"),
1529 quotearg_colon (real_s_name)));
1530
1531 memset (block, 0, BLOCKSIZE);
1532
1533 /* FIXME: Michael P Urban writes: [a long name file] is being written
1534 when a new volume rolls around [...] Looks like the wrong value is
1535 being preserved in real_s_name, though. */
1536
1537 strncpy (block->header.name, real_s_name, NAME_FIELD_SIZE);
1538 block->header.typeflag = GNUTYPE_MULTIVOL;
1539
1540 OFF_TO_CHARS (real_s_sizeleft, block->header.size);
1541 OFF_TO_CHARS (real_s_totsize - real_s_sizeleft,
1542 block->oldgnu_header.offset);
1543
1544 tmp = verbose_option;
1545 verbose_option = 0;
1546 finish_header (&current_stat_info, block, -1);
1547 verbose_option = tmp;
1548 set_next_block_after (block);
1549 }
1550
1551 /* Add a multi volume header to the current archive. The exact header format
1552 depends on the archive format. */
1553 static void
1554 add_multi_volume_header (void)
1555 {
1556 if (archive_format == POSIX_FORMAT)
1557 {
1558 off_t d = real_s_totsize - real_s_sizeleft;
1559 xheader_store ("GNU.volume.filename", &dummy, real_s_name);
1560 xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
1561 xheader_store ("GNU.volume.offset", &dummy, &d);
1562 }
1563 else
1564 gnu_add_multi_volume_header ();
1565 }
1566
1567 /* Synchronize multi-volume globals */
1568 static void
1569 multi_volume_sync ()
1570 {
1571 if (multi_volume_option)
1572 {
1573 if (save_name)
1574 {
1575 assign_string (&real_s_name,
1576 safer_name_suffix (save_name, false,
1577 absolute_names_option));
1578 real_s_totsize = save_totsize;
1579 real_s_sizeleft = save_sizeleft;
1580 }
1581 else
1582 {
1583 assign_string (&real_s_name, 0);
1584 real_s_totsize = 0;
1585 real_s_sizeleft = 0;
1586 }
1587 }
1588 }
1589
1590 \f
1591 /* Low-level flush functions */
1592
1593 /* Simple flush read (no multi-volume or label extensions) */
1594 static void
1595 simple_flush_read (void)
1596 {
1597 size_t status; /* result from system call */
1598
1599 checkpoint_run (false);
1600
1601 /* Clear the count of errors. This only applies to a single call to
1602 flush_read. */
1603
1604 read_error_count = 0; /* clear error count */
1605
1606 if (write_archive_to_stdout && record_start_block != 0)
1607 {
1608 archive = STDOUT_FILENO;
1609 status = sys_write_archive_buffer ();
1610 archive = STDIN_FILENO;
1611 if (status != record_size)
1612 archive_write_error (status);
1613 }
1614
1615 for (;;)
1616 {
1617 status = rmtread (archive, record_start->buffer, record_size);
1618 if (status == record_size)
1619 {
1620 records_read++;
1621 return;
1622 }
1623 if (status == SAFE_READ_ERROR)
1624 {
1625 archive_read_error ();
1626 continue; /* try again */
1627 }
1628 break;
1629 }
1630 short_read (status);
1631 }
1632
1633 /* Simple flush write (no multi-volume or label extensions) */
1634 static void
1635 simple_flush_write (size_t level __attribute__((unused)))
1636 {
1637 ssize_t status;
1638
1639 status = _flush_write ();
1640 if (status != record_size)
1641 archive_write_error (status);
1642 else
1643 {
1644 records_written++;
1645 bytes_written += status;
1646 }
1647 }
1648
1649 \f
1650 /* GNU flush functions. These support multi-volume and archive labels in
1651 GNU and PAX archive formats. */
1652
1653 static void
1654 _gnu_flush_read (void)
1655 {
1656 size_t status; /* result from system call */
1657
1658 checkpoint_run (false);
1659
1660 /* Clear the count of errors. This only applies to a single call to
1661 flush_read. */
1662
1663 read_error_count = 0; /* clear error count */
1664
1665 if (write_archive_to_stdout && record_start_block != 0)
1666 {
1667 archive = STDOUT_FILENO;
1668 status = sys_write_archive_buffer ();
1669 archive = STDIN_FILENO;
1670 if (status != record_size)
1671 archive_write_error (status);
1672 }
1673
1674 multi_volume_sync ();
1675
1676 for (;;)
1677 {
1678 status = rmtread (archive, record_start->buffer, record_size);
1679 if (status == record_size)
1680 {
1681 records_read++;
1682 return;
1683 }
1684
1685 /* The condition below used to include
1686 || (status > 0 && !read_full_records)
1687 This is incorrect since even if new_volume() succeeds, the
1688 subsequent call to rmtread will overwrite the chunk of data
1689 already read in the buffer, so the processing will fail */
1690 if ((status == 0
1691 || (status == SAFE_READ_ERROR && errno == ENOSPC))
1692 && multi_volume_option)
1693 {
1694 while (!try_new_volume ())
1695 ;
1696 if (current_block == record_end)
1697 /* Necessary for blocking_factor == 1 */
1698 flush_archive();
1699 return;
1700 }
1701 else if (status == SAFE_READ_ERROR)
1702 {
1703 archive_read_error ();
1704 continue;
1705 }
1706 break;
1707 }
1708 short_read (status);
1709 }
1710
1711 static void
1712 gnu_flush_read (void)
1713 {
1714 flush_read_ptr = simple_flush_read; /* Avoid recursion */
1715 _gnu_flush_read ();
1716 flush_read_ptr = gnu_flush_read;
1717 }
1718
1719 static void
1720 _gnu_flush_write (size_t buffer_level)
1721 {
1722 ssize_t status;
1723 union block *header;
1724 char *copy_ptr;
1725 size_t copy_size;
1726 size_t bufsize;
1727 tarlong wrt;
1728
1729 status = _flush_write ();
1730 if (status != record_size && !multi_volume_option)
1731 archive_write_error (status);
1732 else
1733 {
1734 if (status)
1735 records_written++;
1736 bytes_written += status;
1737 }
1738
1739 if (status == record_size)
1740 {
1741 multi_volume_sync ();
1742 return;
1743 }
1744
1745 if (status % BLOCKSIZE)
1746 {
1747 ERROR ((0, 0, _("write did not end on a block boundary")));
1748 archive_write_error (status);
1749 }
1750
1751 /* In multi-volume mode. */
1752 /* ENXIO is for the UNIX PC. */
1753 if (status < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
1754 archive_write_error (status);
1755
1756 real_s_sizeleft -= status;
1757 if (!new_volume (ACCESS_WRITE))
1758 return;
1759
1760 tar_stat_destroy (&dummy);
1761
1762 increase_volume_number ();
1763 prev_written += bytes_written;
1764 bytes_written = 0;
1765
1766 copy_ptr = record_start->buffer + status;
1767 copy_size = buffer_level - status;
1768
1769 /* Switch to the next buffer */
1770 record_index = !record_index;
1771 init_buffer ();
1772
1773 if (volume_label_option)
1774 add_volume_label ();
1775
1776 if (real_s_name)
1777 add_multi_volume_header ();
1778
1779 write_extended (true, &dummy, find_next_block ());
1780 tar_stat_destroy (&dummy);
1781
1782 if (real_s_name)
1783 add_chunk_header ();
1784 wrt = bytes_written;
1785 header = find_next_block ();
1786 bufsize = available_space_after (header);
1787 while (bufsize < copy_size)
1788 {
1789 memcpy (header->buffer, copy_ptr, bufsize);
1790 copy_ptr += bufsize;
1791 copy_size -= bufsize;
1792 set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
1793 header = find_next_block ();
1794 bufsize = available_space_after (header);
1795 }
1796 memcpy (header->buffer, copy_ptr, copy_size);
1797 memset (header->buffer + copy_size, 0, bufsize - copy_size);
1798 set_next_block_after (header + (copy_size - 1) / BLOCKSIZE);
1799 if (multi_volume_option && wrt < bytes_written)
1800 {
1801 /* The value of bytes_written has changed while moving data;
1802 that means that flush_archive was executed at least once in
1803 between, and, as a consequence, copy_size bytes were not written
1804 to disk. We need to update sizeleft variables to compensate for
1805 that. */
1806 save_sizeleft += copy_size;
1807 multi_volume_sync ();
1808 }
1809 find_next_block ();
1810 }
1811
1812 static void
1813 gnu_flush_write (size_t buffer_level)
1814 {
1815 flush_write_ptr = simple_flush_write; /* Avoid recursion */
1816 _gnu_flush_write (buffer_level);
1817 flush_write_ptr = gnu_flush_write;
1818 }
1819
1820 void
1821 flush_read ()
1822 {
1823 flush_read_ptr ();
1824 }
1825
1826 void
1827 flush_write ()
1828 {
1829 flush_write_ptr (record_size);
1830 }
1831
1832 void
1833 open_archive (enum access_mode wanted_access)
1834 {
1835 flush_read_ptr = gnu_flush_read;
1836 flush_write_ptr = gnu_flush_write;
1837
1838 _open_archive (wanted_access);
1839 switch (wanted_access)
1840 {
1841 case ACCESS_READ:
1842 if (volume_label_option)
1843 match_volume_label ();
1844 break;
1845
1846 case ACCESS_WRITE:
1847 records_written = 0;
1848 if (volume_label_option)
1849 write_volume_label ();
1850 break;
1851
1852 default:
1853 break;
1854 }
1855 set_volume_start_time ();
1856 }
This page took 0.109036 seconds and 5 git commands to generate.