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