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