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