]> Dogcows Code - chaz/tar/blob - src/buffer.c
*** empty log message ***
[chaz/tar] / src / buffer.c
1 /* Buffer management for tar.
2 Copyright (C) 1988, 1992 Free Software Foundation
3
4 This file is part of GNU Tar.
5
6 GNU Tar is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Tar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Tar; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21 * Buffer management for tar.
22 *
23 * Written by John Gilmore, ihnp4!hoptoad!gnu, on 25 August 1985.
24 */
25
26 #include <stdio.h>
27 #include <errno.h>
28 #ifndef STDC_HEADERS
29 extern int errno;
30 #endif
31 #include <sys/types.h> /* For non-Berkeley systems */
32 #include <signal.h>
33 #include <time.h>
34 time_t time ();
35
36 #ifdef HAVE_SYS_MTIO_H
37 #include <sys/ioctl.h>
38 #include <sys/mtio.h>
39 #endif
40
41 #ifdef BSD42
42 #include <sys/file.h>
43 #else
44 #ifndef V7
45 #include <fcntl.h>
46 #endif
47 #endif
48
49 #ifdef __MSDOS__
50 #include <process.h>
51 #endif
52
53 #ifdef XENIX
54 #include <sys/inode.h>
55 #endif
56
57 #include "tar.h"
58 #include "port.h"
59 #include "rmt.h"
60 #include "regex.h"
61
62 /* Either stdout or stderr: The thing we write messages (standard msgs, not
63 errors) to. Stdout unless we're writing a pipe, in which case stderr */
64 FILE *msg_file = stdout;
65
66 #define STDIN 0 /* Standard input file descriptor */
67 #define STDOUT 1 /* Standard output file descriptor */
68
69 #define PREAD 0 /* Read file descriptor from pipe() */
70 #define PWRITE 1 /* Write file descriptor from pipe() */
71
72 #define MAGIC_STAT 105 /* Magic status returned by child, if
73 it can't exec. We hope compress/sh
74 never return this status! */
75
76 void *valloc ();
77
78 void writeerror ();
79 void readerror ();
80
81 void ck_pipe ();
82 void ck_close ();
83
84 int backspace_output ();
85 extern void finish_header ();
86 void flush_archive ();
87 int isfile ();
88 int new_volume ();
89 void verify_volume ();
90 extern void to_oct ();
91
92 #ifndef __MSDOS__
93 /* Obnoxious test to see if dimwit is trying to dump the archive */
94 dev_t ar_dev;
95 ino_t ar_ino;
96 #endif
97
98 /*
99 * The record pointed to by save_rec should not be overlaid
100 * when reading in a new tape block. Copy it to record_save_area first, and
101 * change the pointer in *save_rec to point to record_save_area.
102 * Saved_recno records the record number at the time of the save.
103 * This is used by annofile() to print the record number of a file's
104 * header record.
105 */
106 static union record **save_rec;
107 union record record_save_area;
108 static long saved_recno;
109
110 /*
111 * PID of child program, if f_compress or remote archive access.
112 */
113 static int childpid = 0;
114
115 /*
116 * Record number of the start of this block of records
117 */
118 long baserec;
119
120 /*
121 * Error recovery stuff
122 */
123 static int r_error_count;
124
125 /*
126 * Have we hit EOF yet?
127 */
128 static int hit_eof;
129
130 /* Checkpointing counter */
131 static int checkpoint;
132
133 /* JF we're reading, but we just read the last record and its time to update */
134 extern time_to_start_writing;
135 int file_to_switch_to = -1; /* If remote update, close archive, and use
136 this descriptor to write to */
137
138 static int volno = 1; /* JF which volume of a multi-volume tape
139 we're on */
140 static int global_volno = 1; /* Volume number to print in external messages. */
141
142 char *save_name = 0; /* Name of the file we are currently writing */
143 long save_totsize; /* total size of file we are writing. Only
144 valid if save_name is non_zero */
145 long save_sizeleft; /* Where we are in the file we are writing.
146 Only valid if save_name is non-zero */
147
148 int write_archive_to_stdout;
149
150 /* Used by fl_read and fl_write to store the real info about saved names */
151 static char real_s_name[NAMSIZ];
152 static long real_s_totsize;
153 static long real_s_sizeleft;
154
155 /* Reset the EOF flag (if set), and re-set ar_record, etc */
156
157 void
158 reset_eof ()
159 {
160 if (hit_eof)
161 {
162 hit_eof = 0;
163 ar_record = ar_block;
164 ar_last = ar_block + blocking;
165 ar_reading = 0;
166 }
167 }
168
169 /*
170 * Return the location of the next available input or output record.
171 * Return NULL for EOF. Once we have returned NULL, we just keep returning
172 * it, to avoid accidentally going on to the next file on the "tape".
173 */
174 union record *
175 findrec ()
176 {
177 if (ar_record == ar_last)
178 {
179 if (hit_eof)
180 return (union record *) NULL; /* EOF */
181 flush_archive ();
182 if (ar_record == ar_last)
183 {
184 hit_eof++;
185 return (union record *) NULL; /* EOF */
186 }
187 }
188 return ar_record;
189 }
190
191
192 /*
193 * Indicate that we have used all records up thru the argument.
194 * (should the arg have an off-by-1? XXX FIXME)
195 */
196 void
197 userec (rec)
198 union record *rec;
199 {
200 while (rec >= ar_record)
201 ar_record++;
202 /*
203 * Do NOT flush the archive here. If we do, the same
204 * argument to userec() could mean the next record (if the
205 * input block is exactly one record long), which is not what
206 * is intended.
207 */
208 if (ar_record > ar_last)
209 abort ();
210 }
211
212
213 /*
214 * Return a pointer to the end of the current records buffer.
215 * All the space between findrec() and endofrecs() is available
216 * for filling with data, or taking data from.
217 */
218 union record *
219 endofrecs ()
220 {
221 return ar_last;
222 }
223
224
225 /*
226 * Duplicate a file descriptor into a certain slot.
227 * Equivalent to BSD "dup2" with error reporting.
228 */
229 void
230 dupto (from, to, msg)
231 int from, to;
232 char *msg;
233 {
234 int err;
235
236 if (from != to)
237 {
238 err = close (to);
239 if (err < 0 && errno != EBADF)
240 {
241 msg_perror ("Cannot close descriptor %d", to);
242 exit (EX_SYSTEM);
243 }
244 err = dup (from);
245 if (err != to)
246 {
247 msg_perror ("cannot dup %s", msg);
248 exit (EX_SYSTEM);
249 }
250 ck_close (from);
251 }
252 }
253
254 #ifdef __MSDOS__
255 void
256 child_open ()
257 {
258 fprintf (stderr, "MS-DOS %s can't use compressed or remote archives\n", tar);
259 exit (EX_ARGSBAD);
260 }
261
262 #else
263 void
264 child_open ()
265 {
266 int pipe[2];
267 int err = 0;
268 int nar;
269
270 int kidpipe[2];
271 int kidchildpid;
272
273 #define READ 0
274 #define WRITE 1
275
276 ck_pipe (pipe);
277
278 childpid = fork ();
279 if (childpid < 0)
280 {
281 msg_perror ("cannot fork");
282 exit (EX_SYSTEM);
283 }
284 if (childpid > 0)
285 {
286 /* We're the parent. Clean up and be happy */
287 /* This, at least, is easy */
288
289 if (ar_reading)
290 {
291 f_reblock++;
292 archive = pipe[READ];
293 ck_close (pipe[WRITE]);
294 }
295 else
296 {
297 archive = pipe[WRITE];
298 ck_close (pipe[READ]);
299 }
300 return;
301 }
302
303 /* We're the kid */
304 if (ar_reading)
305 {
306 dupto (pipe[WRITE], STDOUT, "(child) pipe to stdout");
307 ck_close (pipe[READ]);
308 }
309 else
310 {
311 dupto (pipe[READ], STDIN, "(child) pipe to stdin");
312 ck_close (pipe[WRITE]);
313 }
314
315 /* We need a child tar only if
316 1: we're reading/writing stdin/out (to force reblocking)
317 2: the file is to be accessed by rmt (compress doesn't know how)
318 3: the file is not a plain file */
319 #ifdef NO_REMOTE
320 if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && isfile (ar_files[0]))
321 #else
322 if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && !_remdev (ar_files[0]) && isfile (ar_files[0]))
323 #endif
324 {
325 /* We don't need a child tar. Open the archive */
326 if (ar_reading)
327 {
328 archive = open (ar_files[0], O_RDONLY | O_BINARY, 0666);
329 if (archive < 0)
330 {
331 msg_perror ("can't open archive %s", ar_files[0]);
332 exit (EX_BADARCH);
333 }
334 dupto (archive, STDIN, "archive to stdin");
335 /* close(archive); */
336 }
337 else
338 {
339 archive = creat (ar_files[0], 0666);
340 if (archive < 0)
341 {
342 msg_perror ("can't open archive %s", ar_files[0]);
343 exit (EX_BADARCH);
344 }
345 dupto (archive, STDOUT, "archive to stdout");
346 /* close(archive); */
347 }
348 }
349 else
350 {
351 /* We need a child tar */
352 ck_pipe (kidpipe);
353
354 kidchildpid = fork ();
355 if (kidchildpid < 0)
356 {
357 msg_perror ("child can't fork");
358 exit (EX_SYSTEM);
359 }
360
361 if (kidchildpid > 0)
362 {
363 /* About to exec compress: set up the files */
364 if (ar_reading)
365 {
366 dupto (kidpipe[READ], STDIN, "((child)) pipe to stdin");
367 ck_close (kidpipe[WRITE]);
368 /* dup2(pipe[WRITE],STDOUT); */
369 }
370 else
371 {
372 /* dup2(pipe[READ],STDIN); */
373 dupto (kidpipe[WRITE], STDOUT, "((child)) pipe to stdout");
374 ck_close (kidpipe[READ]);
375 }
376 /* ck_close(pipe[READ]); */
377 /* ck_close(pipe[WRITE]); */
378 /* ck_close(kidpipe[READ]);
379 ck_close(kidpipe[WRITE]); */
380 }
381 else
382 {
383 /* Grandchild. Do the right thing, namely sit here and
384 read/write the archive, and feed stuff back to compress */
385 tar = "tar (child)";
386 if (ar_reading)
387 {
388 dupto (kidpipe[WRITE], STDOUT, "[child] pipe to stdout");
389 ck_close (kidpipe[READ]);
390 }
391 else
392 {
393 dupto (kidpipe[READ], STDIN, "[child] pipe to stdin");
394 ck_close (kidpipe[WRITE]);
395 }
396
397 if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
398 {
399 if (ar_reading)
400 archive = STDIN;
401 else
402 archive = STDOUT;
403 }
404 else /* This can't happen if (ar_reading==2)
405 archive = rmtopen(ar_files[0], O_RDWR|O_CREAT|O_BINARY, 0666);
406 else */ if (ar_reading)
407 archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
408 else
409 archive = rmtcreat (ar_files[0], 0666);
410
411 if (archive < 0)
412 {
413 msg_perror ("can't open archive %s", ar_files[0]);
414 exit (EX_BADARCH);
415 }
416
417 if (ar_reading)
418 {
419 for (;;)
420 {
421 char *ptr;
422 int max, count;
423
424 r_error_count = 0;
425 error_loop:
426 err = rmtread (archive, ar_block->charptr, (int) (blocksize));
427 if (err < 0)
428 {
429 readerror ();
430 goto error_loop;
431 }
432 if (err == 0)
433 break;
434 ptr = ar_block->charptr;
435 max = err;
436 while (max)
437 {
438 count = (max < RECORDSIZE) ? max : RECORDSIZE;
439 err = write (STDOUT, ptr, count);
440 if (err != count)
441 {
442 if (err < 0)
443 {
444 msg_perror ("can't write to compress");
445 exit (EX_SYSTEM);
446 }
447 else
448 msg ("write to compress short %d bytes", count - err);
449 count = (err < 0) ? 0 : err;
450 }
451 ptr += count;
452 max -= count;
453 }
454 }
455 }
456 else
457 {
458 for (;;)
459 {
460 int n;
461 char *ptr;
462
463 n = blocksize;
464 ptr = ar_block->charptr;
465 while (n)
466 {
467 err = read (STDIN, ptr, (n < RECORDSIZE) ? n : RECORDSIZE);
468 if (err <= 0)
469 break;
470 n -= err;
471 ptr += err;
472 }
473 /* EOF */
474 if (err == 0)
475 {
476 if (f_compress < 2)
477 blocksize -= n;
478 else
479 bzero (ar_block->charptr + blocksize - n, n);
480 err = rmtwrite (archive, ar_block->charptr, blocksize);
481 if (err != (blocksize))
482 writeerror (err);
483 if (f_compress < 2)
484 blocksize += n;
485 break;
486 }
487 if (n)
488 {
489 msg_perror ("can't read from compress");
490 exit (EX_SYSTEM);
491 }
492 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
493 if (err != blocksize)
494 writeerror (err);
495 }
496 }
497
498 /* close_archive(); */
499 exit (0);
500 }
501 }
502 /* So we should exec compress (-d) */
503 if (ar_reading)
504 execlp ("compress", "compress", "-d", (char *) 0);
505 else
506 execlp ("compress", "compress", (char *) 0);
507 msg_perror ("can't exec compress");
508 _exit (EX_SYSTEM);
509 }
510
511
512 /* return non-zero if p is the name of a directory */
513 int
514 isfile (p)
515 char *p;
516 {
517 struct stat stbuf;
518
519 if (stat (p, &stbuf) < 0)
520 return 1;
521 if (S_ISREG (stbuf.st_mode))
522 return 1;
523 return 0;
524 }
525
526 #endif
527
528 /*
529 * Open an archive file. The argument specifies whether we are
530 * reading or writing.
531 */
532 /* JF if the arg is 2, open for reading and writing. */
533 void
534 open_archive (reading)
535 int reading;
536 {
537 msg_file = f_exstdout ? stderr : stdout;
538
539 if (blocksize == 0)
540 {
541 msg ("invalid value for blocksize");
542 exit (EX_ARGSBAD);
543 }
544
545 if (n_ar_files == 0)
546 {
547 msg ("No archive name given, what should I do?");
548 exit (EX_BADARCH);
549 }
550
551 /*NOSTRICT*/
552 if (f_multivol)
553 {
554 ar_block = (union record *) valloc ((unsigned) (blocksize + (2 * RECORDSIZE)));
555 if (ar_block)
556 ar_block += 2;
557 }
558 else
559 ar_block = (union record *) valloc ((unsigned) blocksize);
560 if (!ar_block)
561 {
562 msg ("could not allocate memory for blocking factor %d",
563 blocking);
564 exit (EX_ARGSBAD);
565 }
566
567 ar_record = ar_block;
568 ar_last = ar_block + blocking;
569 ar_reading = reading;
570
571 if (f_multivol && f_verify)
572 {
573 msg ("cannot verify multi-volume archives");
574 exit (EX_ARGSBAD);
575 }
576
577 if (f_compress)
578 {
579 if (reading == 2 || f_verify)
580 {
581 msg ("cannot update or verify compressed archives");
582 exit (EX_ARGSBAD);
583 }
584 if (f_multivol)
585 {
586 msg ("cannot use multi-volume compressed archives");
587 exit (EX_ARGSBAD);
588 }
589 child_open ();
590 if (!reading && ar_files[0][0] == '-' && ar_files[0][1] == '\0')
591 msg_file = stderr;
592 /* child_open(rem_host, rem_file); */
593 }
594 else if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
595 {
596 f_reblock++; /* Could be a pipe, be safe */
597 if (f_verify)
598 {
599 msg ("can't verify stdin/stdout archive");
600 exit (EX_ARGSBAD);
601 }
602 if (reading == 2)
603 {
604 archive = STDIN;
605 msg_file = stderr;
606 write_archive_to_stdout++;
607 }
608 else if (reading)
609 archive = STDIN;
610 else
611 {
612 archive = STDOUT;
613 msg_file = stderr;
614 }
615 }
616 else if (reading == 2 || f_verify)
617 {
618 archive = rmtopen (ar_files[0], O_RDWR | O_CREAT | O_BINARY, 0666);
619 }
620 else if (reading)
621 {
622 archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
623 }
624 else
625 {
626 archive = rmtcreat (ar_files[0], 0666);
627 }
628 if (archive < 0)
629 {
630 msg_perror ("can't open %s", ar_files[0]);
631 exit (EX_BADARCH);
632 }
633 #ifndef __MSDOS__
634 if (!_isrmt (archive))
635 {
636 struct stat tmp_stat;
637
638 fstat (archive, &tmp_stat);
639 if (S_ISREG (tmp_stat.st_mode))
640 {
641 ar_dev = tmp_stat.st_dev;
642 ar_ino = tmp_stat.st_ino;
643 }
644 }
645 #endif
646
647 #ifdef __MSDOS__
648 setmode (archive, O_BINARY);
649 #endif
650
651 if (reading)
652 {
653 ar_last = ar_block; /* Set up for 1st block = # 0 */
654 (void) findrec (); /* Read it in, check for EOF */
655
656 if (f_volhdr)
657 {
658 union record *head;
659 #if 0
660 char *ptr;
661
662 if (f_multivol)
663 {
664 ptr = malloc (strlen (f_volhdr) + 20);
665 sprintf (ptr, "%s Volume %d", f_volhdr, 1);
666 }
667 else
668 ptr = f_volhdr;
669 #endif
670 head = findrec ();
671 if (!head)
672 {
673 msg ("Archive not labelled to match %s", f_volhdr);
674 exit (EX_BADVOL);
675 }
676 if (re_match (label_pattern, head->header.arch_name,
677 strlen (head->header.arch_name), 0, 0) < 0)
678 {
679 msg ("Volume mismatch! %s!=%s", f_volhdr,
680 head->header.arch_name);
681 exit (EX_BADVOL);
682 }
683 #if 0
684 if (strcmp (ptr, head->header.name))
685 {
686 msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
687 exit (EX_BADVOL);
688 }
689 if (ptr != f_volhdr)
690 free (ptr);
691 #endif
692 }
693 }
694 else if (f_volhdr)
695 {
696 bzero ((void *) ar_block, RECORDSIZE);
697 if (f_multivol)
698 sprintf (ar_block->header.arch_name, "%s Volume 1", f_volhdr);
699 else
700 strcpy (ar_block->header.arch_name, f_volhdr);
701 ar_block->header.linkflag = LF_VOLHDR;
702 to_oct (time (0), 1 + 12, ar_block->header.mtime);
703 finish_header (ar_block);
704 /* ar_record++; */
705 }
706 }
707
708
709 /*
710 * Remember a union record * as pointing to something that we
711 * need to keep when reading onward in the file. Only one such
712 * thing can be remembered at once, and it only works when reading
713 * an archive.
714 *
715 * We calculate "offset" then add it because some compilers end up
716 * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
717 * subtracting ar_block from that, shifting it back, losing the top 9 bits.
718 */
719 void
720 saverec (pointer)
721 union record **pointer;
722 {
723 long offset;
724
725 save_rec = pointer;
726 offset = ar_record - ar_block;
727 saved_recno = baserec + offset;
728 }
729
730 /*
731 * Perform a write to flush the buffer.
732 */
733
734 /*send_buffer_to_file();
735 if(new_volume) {
736 deal_with_new_volume_stuff();
737 send_buffer_to_file();
738 }
739 */
740
741 void
742 fl_write ()
743 {
744 int err;
745 int copy_back;
746 static long bytes_written = 0;
747
748 if (f_checkpoint && !(++checkpoint % 10))
749 msg ("Write checkpoint %d\n", checkpoint);
750 if (tape_length && bytes_written >= tape_length * 1024)
751 {
752 errno = ENOSPC;
753 err = 0;
754 }
755 else
756 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
757 if (err != blocksize && !f_multivol)
758 writeerror (err);
759 else if (f_totals)
760 tot_written += blocksize;
761
762 if (err > 0)
763 bytes_written += err;
764 if (err == blocksize)
765 {
766 if (f_multivol)
767 {
768 if (!save_name)
769 {
770 real_s_name[0] = '\0';
771 real_s_totsize = 0;
772 real_s_sizeleft = 0;
773 return;
774 }
775 #ifdef __MSDOS__
776 if (save_name[1] == ':')
777 save_name += 2;
778 #endif
779 while (*save_name == '/')
780 save_name++;
781
782 strcpy (real_s_name, save_name);
783 real_s_totsize = save_totsize;
784 real_s_sizeleft = save_sizeleft;
785 }
786 return;
787 }
788
789 /* We're multivol Panic if we didn't get the right kind of response */
790 /* ENXIO is for the UNIX PC */
791 if (err < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
792 writeerror (err);
793
794 /* If error indicates a short write, we just move to the next tape. */
795
796 if (new_volume (0) < 0)
797 return;
798 bytes_written = 0;
799 if (f_volhdr && real_s_name[0])
800 {
801 copy_back = 2;
802 ar_block -= 2;
803 }
804 else if (f_volhdr || real_s_name[0])
805 {
806 copy_back = 1;
807 ar_block--;
808 }
809 else
810 copy_back = 0;
811 if (f_volhdr)
812 {
813 bzero ((void *) ar_block, RECORDSIZE);
814 sprintf (ar_block->header.arch_name, "%s Volume %d", f_volhdr, volno);
815 to_oct (time (0), 1 + 12, ar_block->header.mtime);
816 ar_block->header.linkflag = LF_VOLHDR;
817 finish_header (ar_block);
818 }
819 if (real_s_name[0])
820 {
821 int tmp;
822
823 if (f_volhdr)
824 ar_block++;
825 bzero ((void *) ar_block, RECORDSIZE);
826 strcpy (ar_block->header.arch_name, real_s_name);
827 ar_block->header.linkflag = LF_MULTIVOL;
828 to_oct ((long) real_s_sizeleft, 1 + 12,
829 ar_block->header.size);
830 to_oct ((long) real_s_totsize - real_s_sizeleft,
831 1 + 12, ar_block->header.offset);
832 tmp = f_verbose;
833 f_verbose = 0;
834 finish_header (ar_block);
835 f_verbose = tmp;
836 if (f_volhdr)
837 ar_block--;
838 }
839
840 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
841 if (err != blocksize)
842 writeerror (err);
843 else if (f_totals)
844 tot_written += blocksize;
845
846
847 bytes_written = blocksize;
848 if (copy_back)
849 {
850 ar_block += copy_back;
851 bcopy ((void *) (ar_block + blocking - copy_back),
852 (void *) ar_record,
853 copy_back * RECORDSIZE);
854 ar_record += copy_back;
855
856 if (real_s_sizeleft >= copy_back * RECORDSIZE)
857 real_s_sizeleft -= copy_back * RECORDSIZE;
858 else if ((real_s_sizeleft + RECORDSIZE - 1) / RECORDSIZE <= copy_back)
859 real_s_name[0] = '\0';
860 else
861 {
862 #ifdef __MSDOS__
863 if (save_name[1] == ':')
864 save_name += 2;
865 #endif
866 while (*save_name == '/')
867 save_name++;
868
869 strcpy (real_s_name, save_name);
870 real_s_sizeleft = save_sizeleft;
871 real_s_totsize = save_totsize;
872 }
873 copy_back = 0;
874 }
875 }
876
877 /* Handle write errors on the archive. Write errors are always fatal */
878 /* Hitting the end of a volume does not cause a write error unless the write
879 * was the first block of the volume */
880
881 void
882 writeerror (err)
883 int err;
884 {
885 if (err < 0)
886 {
887 msg_perror ("can't write to %s", ar_files[cur_ar_file]);
888 exit (EX_BADARCH);
889 }
890 else
891 {
892 msg ("only wrote %u of %u bytes to %s", err, blocksize, ar_files[cur_ar_file]);
893 exit (EX_BADARCH);
894 }
895 }
896
897 /*
898 * Handle read errors on the archive.
899 *
900 * If the read should be retried, readerror() returns to the caller.
901 */
902 void
903 readerror ()
904 {
905 # define READ_ERROR_MAX 10
906
907 read_error_flag++; /* Tell callers */
908
909 msg_perror ("read error on %s", ar_files[cur_ar_file]);
910
911 if (baserec == 0)
912 {
913 /* First block of tape. Probably stupidity error */
914 exit (EX_BADARCH);
915 }
916
917 /*
918 * Read error in mid archive. We retry up to READ_ERROR_MAX times
919 * and then give up on reading the archive. We set read_error_flag
920 * for our callers, so they can cope if they want.
921 */
922 if (r_error_count++ > READ_ERROR_MAX)
923 {
924 msg ("Too many errors, quitting.");
925 exit (EX_BADARCH);
926 }
927 return;
928 }
929
930
931 /*
932 * Perform a read to flush the buffer.
933 */
934 void
935 fl_read ()
936 {
937 int err; /* Result from system call */
938 int left; /* Bytes left */
939 char *more; /* Pointer to next byte to read */
940
941 if (f_checkpoint && !(++checkpoint % 10))
942 msg ("Read checkpoint %d\n", checkpoint);
943
944 /*
945 * Clear the count of errors. This only applies to a single
946 * call to fl_read. We leave read_error_flag alone; it is
947 * only turned off by higher level software.
948 */
949 r_error_count = 0; /* Clear error count */
950
951 /*
952 * If we are about to wipe out a record that
953 * somebody needs to keep, copy it out to a holding
954 * area and adjust somebody's pointer to it.
955 */
956 if (save_rec &&
957 *save_rec >= ar_record &&
958 *save_rec < ar_last)
959 {
960 record_save_area = **save_rec;
961 *save_rec = &record_save_area;
962 }
963 if (write_archive_to_stdout && baserec != 0)
964 {
965 err = rmtwrite (1, ar_block->charptr, blocksize);
966 if (err != blocksize)
967 writeerror (err);
968 }
969 if (f_multivol)
970 {
971 if (save_name)
972 {
973 if (save_name != real_s_name)
974 {
975 #ifdef __MSDOS__
976 if (save_name[1] == ':')
977 save_name += 2;
978 #endif
979 while (*save_name == '/')
980 save_name++;
981
982 strcpy (real_s_name, save_name);
983 save_name = real_s_name;
984 }
985 real_s_totsize = save_totsize;
986 real_s_sizeleft = save_sizeleft;
987
988 }
989 else
990 {
991 real_s_name[0] = '\0';
992 real_s_totsize = 0;
993 real_s_sizeleft = 0;
994 }
995 }
996
997 error_loop:
998 err = rmtread (archive, ar_block->charptr, (int) blocksize);
999 if (err == blocksize)
1000 return;
1001
1002 if ((err == 0 || (err < 0 && errno == ENOSPC) || (err > 0 && !f_reblock)) && f_multivol)
1003 {
1004 union record *head;
1005
1006 try_volume:
1007 if (new_volume ((cmd_mode == CMD_APPEND || cmd_mode == CMD_CAT || cmd_mode == CMD_UPDATE) ? 2 : 1) < 0)
1008 return;
1009 vol_error:
1010 err = rmtread (archive, ar_block->charptr, (int) blocksize);
1011 if (err < 0)
1012 {
1013 readerror ();
1014 goto vol_error;
1015 }
1016 if (err != blocksize)
1017 goto short_read;
1018
1019 head = ar_block;
1020
1021 if (head->header.linkflag == LF_VOLHDR)
1022 {
1023 if (f_volhdr)
1024 {
1025 #if 0
1026 char *ptr;
1027
1028 ptr = (char *) malloc (strlen (f_volhdr) + 20);
1029 sprintf (ptr, "%s Volume %d", f_volhdr, volno);
1030 #endif
1031 if (re_match (label_pattern, head->header.arch_name,
1032 strlen (head->header.arch_name),
1033 0, 0) < 0)
1034 {
1035 msg ("Volume mismatch! %s!=%s", f_volhdr,
1036 head->header.arch_name);
1037 --volno;
1038 --global_volno;
1039 goto try_volume;
1040 }
1041
1042 #if 0
1043 if (strcmp (ptr, head->header.name))
1044 {
1045 msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
1046 --volno;
1047 --global_volno;
1048 free (ptr);
1049 goto try_volume;
1050 }
1051 free (ptr);
1052 #endif
1053 }
1054 if (f_verbose)
1055 fprintf (msg_file, "Reading %s\n", head->header.arch_name);
1056 head++;
1057 }
1058 else if (f_volhdr)
1059 {
1060 msg ("Warning: No volume header!");
1061 }
1062
1063 if (real_s_name[0])
1064 {
1065 long from_oct ();
1066
1067 if (head->header.linkflag != LF_MULTIVOL || strcmp (head->header.arch_name, real_s_name))
1068 {
1069 msg ("%s is not continued on this volume!", real_s_name);
1070 --volno;
1071 --global_volno;
1072 goto try_volume;
1073 }
1074 if (real_s_totsize != from_oct (1 + 12, head->header.size) + from_oct (1 + 12, head->header.offset))
1075 {
1076 msg ("%s is the wrong size (%ld!=%ld+%ld)",
1077 head->header.arch_name, save_totsize,
1078 from_oct (1 + 12, head->header.size),
1079 from_oct (1 + 12, head->header.offset));
1080 --volno;
1081 --global_volno;
1082 goto try_volume;
1083 }
1084 if (real_s_totsize - real_s_sizeleft != from_oct (1 + 12, head->header.offset))
1085 {
1086 msg ("This volume is out of sequence");
1087 --volno;
1088 --global_volno;
1089 goto try_volume;
1090 }
1091 head++;
1092 }
1093 ar_record = head;
1094 return;
1095 }
1096 else if (err < 0)
1097 {
1098 readerror ();
1099 goto error_loop; /* Try again */
1100 }
1101
1102 short_read:
1103 more = ar_block->charptr + err;
1104 left = blocksize - err;
1105
1106 again:
1107 if (0 == (((unsigned) left) % RECORDSIZE))
1108 {
1109 /* FIXME, for size=0, multi vol support */
1110 /* On the first block, warn about the problem */
1111 if (!f_reblock && baserec == 0 && f_verbose && err > 0)
1112 {
1113 /* msg("Blocksize = %d record%s",
1114 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
1115 msg ("Blocksize = %d records", err / RECORDSIZE);
1116 }
1117 ar_last = ar_block + ((unsigned) (blocksize - left)) / RECORDSIZE;
1118 return;
1119 }
1120 if (f_reblock)
1121 {
1122 /*
1123 * User warned us about this. Fix up.
1124 */
1125 if (left > 0)
1126 {
1127 error2loop:
1128 err = rmtread (archive, more, (int) left);
1129 if (err < 0)
1130 {
1131 readerror ();
1132 goto error2loop; /* Try again */
1133 }
1134 if (err == 0)
1135 {
1136 msg ("archive %s EOF not on block boundary", ar_files[cur_ar_file]);
1137 exit (EX_BADARCH);
1138 }
1139 left -= err;
1140 more += err;
1141 goto again;
1142 }
1143 }
1144 else
1145 {
1146 msg ("only read %d bytes from archive %s", err, ar_files[cur_ar_file]);
1147 exit (EX_BADARCH);
1148 }
1149 }
1150
1151
1152 /*
1153 * Flush the current buffer to/from the archive.
1154 */
1155 void
1156 flush_archive ()
1157 {
1158 int c;
1159
1160 baserec += ar_last - ar_block;/* Keep track of block #s */
1161 ar_record = ar_block; /* Restore pointer to start */
1162 ar_last = ar_block + blocking;/* Restore pointer to end */
1163
1164 if (ar_reading)
1165 {
1166 if (time_to_start_writing)
1167 {
1168 time_to_start_writing = 0;
1169 ar_reading = 0;
1170
1171 if (file_to_switch_to >= 0)
1172 {
1173 if ((c = rmtclose (archive)) < 0)
1174 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1175
1176 archive = file_to_switch_to;
1177 }
1178 else
1179 (void) backspace_output ();
1180 fl_write ();
1181 }
1182 else
1183 fl_read ();
1184 }
1185 else
1186 {
1187 fl_write ();
1188 }
1189 }
1190
1191 /* Backspace the archive descriptor by one blocks worth.
1192 If its a tape, MTIOCTOP will work. If its something else,
1193 we try to seek on it. If we can't seek, we lose! */
1194 int
1195 backspace_output ()
1196 {
1197 long cur;
1198 /* int er; */
1199 extern char *output_start;
1200
1201 #ifdef MTIOCTOP
1202 struct mtop t;
1203
1204 t.mt_op = MTBSR;
1205 t.mt_count = 1;
1206 if ((rmtioctl (archive, MTIOCTOP, &t)) >= 0)
1207 return 1;
1208 if (errno == EIO && (rmtioctl (archive, MTIOCTOP, &t)) >= 0)
1209 return 1;
1210 #endif
1211
1212 cur = rmtlseek (archive, 0L, 1);
1213 cur -= blocksize;
1214 /* Seek back to the beginning of this block and
1215 start writing there. */
1216
1217 if (rmtlseek (archive, cur, 0) != cur)
1218 {
1219 /* Lseek failed. Try a different method */
1220 msg ("Couldn't backspace archive file. It may be unreadable without -i.");
1221 /* Replace the first part of the block with nulls */
1222 if (ar_block->charptr != output_start)
1223 bzero (ar_block->charptr, output_start - ar_block->charptr);
1224 return 2;
1225 }
1226 return 3;
1227 }
1228
1229
1230 /*
1231 * Close the archive file.
1232 */
1233 void
1234 close_archive ()
1235 {
1236 int child;
1237 int status;
1238 int c;
1239
1240 if (time_to_start_writing || !ar_reading)
1241 flush_archive ();
1242 if (cmd_mode == CMD_DELETE)
1243 {
1244 off_t pos;
1245
1246 pos = rmtlseek (archive, 0L, 1);
1247 #ifndef __MSDOS__
1248 (void) ftruncate (archive, pos);
1249 #else
1250 (void) rmtwrite (archive, "", 0);
1251 #endif
1252 }
1253 if (f_verify)
1254 verify_volume ();
1255
1256 if ((c = rmtclose (archive)) < 0)
1257 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1258
1259 #ifndef __MSDOS__
1260 if (childpid)
1261 {
1262 /*
1263 * Loop waiting for the right child to die, or for
1264 * no more kids.
1265 */
1266 while (((child = wait (&status)) != childpid) && child != -1)
1267 ;
1268
1269 if (child != -1)
1270 {
1271 if (WIFSIGNALED (status))
1272 {
1273 /* SIGPIPE is OK, everything else is a problem. */
1274 if (WTERMSIG (status) != SIGPIPE)
1275 msg ("child died with signal %d%s", WTERMSIG (status),
1276 WIFCOREDUMPED (status) ? " (core dumped)" : "");
1277 }
1278 else
1279 {
1280 /* Child voluntarily terminated -- but why? */
1281 if (WEXITSTATUS (status) == MAGIC_STAT)
1282 {
1283 exit (EX_SYSTEM); /* Child had trouble */
1284 }
1285 if (WEXITSTATUS (status) == (SIGPIPE + 128))
1286 {
1287 /*
1288 * /bin/sh returns this if its child
1289 * dies with SIGPIPE. 'Sok.
1290 */
1291 break;
1292 }
1293 else if (WEXITSTATUS (status))
1294 msg ("child returned status %d",
1295 WEXITSTATUS (status));
1296 }
1297 }
1298 }
1299 #endif /* __MSDOS__ */
1300 }
1301
1302
1303 #ifdef DONTDEF
1304 /*
1305 * Message management.
1306 *
1307 * anno writes a message prefix on stream (eg stdout, stderr).
1308 *
1309 * The specified prefix is normally output followed by a colon and a space.
1310 * However, if other command line options are set, more output can come
1311 * out, such as the record # within the archive.
1312 *
1313 * If the specified prefix is NULL, no output is produced unless the
1314 * command line option(s) are set.
1315 *
1316 * If the third argument is 1, the "saved" record # is used; if 0, the
1317 * "current" record # is used.
1318 */
1319 void
1320 anno (stream, prefix, savedp)
1321 FILE *stream;
1322 char *prefix;
1323 int savedp;
1324 {
1325 # define MAXANNO 50
1326 char buffer[MAXANNO]; /* Holds annorecment */
1327 # define ANNOWIDTH 13
1328 int space;
1329 long offset;
1330 int save_e;
1331
1332 save_e = errno;
1333 /* Make sure previous output gets out in sequence */
1334 if (stream == stderr)
1335 fflush (stdout);
1336 if (f_sayblock)
1337 {
1338 if (prefix)
1339 {
1340 fputs (prefix, stream);
1341 putc (' ', stream);
1342 }
1343 offset = ar_record - ar_block;
1344 (void) sprintf (buffer, "rec %d: ",
1345 savedp ? saved_recno :
1346 baserec + offset);
1347 fputs (buffer, stream);
1348 space = ANNOWIDTH - strlen (buffer);
1349 if (space > 0)
1350 {
1351 fprintf (stream, "%*s", space, "");
1352 }
1353 }
1354 else if (prefix)
1355 {
1356 fputs (prefix, stream);
1357 fputs (": ", stream);
1358 }
1359 errno = save_e;
1360 }
1361 #endif
1362
1363 /* Called to initialize the global volume number. */
1364 int
1365 init_volume_number ()
1366 {
1367 FILE *vf;
1368
1369 vf = fopen (f_volno_file, "r");
1370 if (!vf && errno != ENOENT)
1371 msg_perror ("%s", f_volno_file);
1372
1373 if (vf)
1374 {
1375 fscanf (vf, "%d", &global_volno);
1376 fclose (vf);
1377 }
1378 }
1379
1380 /* Called to write out the closing global volume number. */
1381 int
1382 closeout_volume_number ()
1383 {
1384 FILE *vf;
1385
1386 vf = fopen (f_volno_file, "w");
1387 if (!vf)
1388 msg_perror ("%s", f_volno_file);
1389 else
1390 {
1391 fprintf (vf, "%d\n", global_volno);
1392 fclose (vf);
1393 }
1394 }
1395
1396 /* We've hit the end of the old volume. Close it and open the next one */
1397 /* Values for type: 0: writing 1: reading 2: updating */
1398 int
1399 new_volume (type)
1400 int type;
1401 {
1402 int c;
1403 char inbuf[80];
1404 char *p;
1405 static FILE *read_file = 0;
1406 extern int now_verifying;
1407 extern char TTY_NAME[];
1408 static int looped = 0;
1409
1410 if (!read_file && !f_run_script_at_end)
1411 read_file = (archive == 0) ? fopen (TTY_NAME, "r") : stdin;
1412
1413 if (now_verifying)
1414 return -1;
1415 if (f_verify)
1416 verify_volume ();
1417 if ((c = rmtclose (archive)) < 0)
1418 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1419
1420 global_volno++;
1421 volno++;
1422 cur_ar_file++;
1423 if (cur_ar_file == n_ar_files)
1424 {
1425 cur_ar_file = 0;
1426 looped = 1;
1427 }
1428
1429 tryagain:
1430 if (looped)
1431 {
1432 /* We have to prompt from now on. */
1433 if (f_run_script_at_end)
1434 system (info_script);
1435 else
1436 for (;;)
1437 {
1438 fprintf (msg_file, "\007Prepare volume #%d for %s and hit return: ", global_volno, ar_files[cur_ar_file]);
1439 fflush (msg_file);
1440 if (fgets (inbuf, sizeof (inbuf), read_file) == 0)
1441 {
1442 fprintf (msg_file, "EOF? What does that mean?");
1443 if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
1444 msg ("Warning: Archive is INCOMPLETE!");
1445 exit (EX_BADARCH);
1446 }
1447 if (inbuf[0] == '\n' || inbuf[0] == 'y' || inbuf[0] == 'Y')
1448 break;
1449
1450 switch (inbuf[0])
1451 {
1452 case '?':
1453 {
1454 fprintf (msg_file, "\
1455 n [name] Give a new filename for the next (and subsequent) volume(s)\n\
1456 q Abort tar\n\
1457 ! Spawn a subshell\n\
1458 ? Print this list\n");
1459 }
1460 break;
1461
1462 case 'q': /* Quit */
1463 fprintf (msg_file, "No new volume; exiting.\n");
1464 if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
1465 msg ("Warning: Archive is INCOMPLETE!");
1466 exit (EX_BADARCH);
1467
1468 case 'n': /* Get new file name */
1469 {
1470 char *q, *r;
1471 static char *old_name;
1472
1473 for (q = &inbuf[1]; *q == ' ' || *q == '\t'; q++)
1474 ;
1475 for (r = q; *r; r++)
1476 if (*r == '\n')
1477 *r = '\0';
1478 old_name = p = (char *) malloc ((unsigned) (strlen (q) + 2));
1479 if (p == 0)
1480 {
1481 msg ("Can't allocate memory for name");
1482 exit (EX_SYSTEM);
1483 }
1484 (void) strcpy (p, q);
1485 ar_files[cur_ar_file] = p;
1486 }
1487 break;
1488
1489 case '!':
1490 #ifdef __MSDOS__
1491 spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
1492 #else
1493 /* JF this needs work! */
1494 switch (fork ())
1495 {
1496 case -1:
1497 msg_perror ("can't fork!");
1498 break;
1499 case 0:
1500 p = getenv ("SHELL");
1501 if (p == 0)
1502 p = "/bin/sh";
1503 execlp (p, "-sh", "-i", 0);
1504 msg_perror ("can't exec a shell %s", p);
1505 _exit (55);
1506 default:
1507 wait (0);
1508 break;
1509 }
1510 #endif
1511 break;
1512 }
1513 }
1514 }
1515
1516
1517 if (type == 2 || f_verify)
1518 archive = rmtopen (ar_files[cur_ar_file], O_RDWR | O_CREAT, 0666);
1519 else if (type == 1)
1520 archive = rmtopen (ar_files[cur_ar_file], O_RDONLY, 0666);
1521 else if (type == 0)
1522 archive = rmtcreat (ar_files[cur_ar_file], 0666);
1523 else
1524 archive = -1;
1525
1526 if (archive < 0)
1527 {
1528 msg_perror ("can't open %s", ar_files[cur_ar_file]);
1529 goto tryagain;
1530 }
1531 #ifdef __MSDOS__
1532 setmode (archive, O_BINARY);
1533 #endif
1534 return 0;
1535 }
1536
1537 /* this is a useless function that takes a buffer returned by wantbytes
1538 and does nothing with it. If the function called by wantbytes returns
1539 an error indicator (non-zero), this function is called for the rest of
1540 the file.
1541 */
1542 int
1543 no_op (size, data)
1544 int size;
1545 char *data;
1546 {
1547 return 0;
1548 }
1549
1550 /* Some other routine wants SIZE bytes in the archive. For each chunk of
1551 the archive, call FUNC with the size of the chunk, and the address of
1552 the chunk it can work with.
1553 */
1554 int
1555 wantbytes (size, func)
1556 long size;
1557 int (*func) ();
1558 {
1559 char *data;
1560 long data_size;
1561
1562 while (size)
1563 {
1564 data = findrec ()->charptr;
1565 if (data == NULL)
1566 { /* Check it... */
1567 msg ("Unexpected EOF on archive file");
1568 return -1;
1569 }
1570 data_size = endofrecs ()->charptr - data;
1571 if (data_size > size)
1572 data_size = size;
1573 if ((*func) (data_size, data))
1574 func = no_op;
1575 userec ((union record *) (data + data_size - 1));
1576 size -= data_size;
1577 }
1578 return 0;
1579 }
This page took 0.111578 seconds and 5 git commands to generate.