source: trunk/essentials/app-arch/tar/src/buffer.c

Last change on this file was 3356, checked in by bird, 18 years ago

Set binary mode on stdout when we're reading stdin and writing stdout.

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