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