]> 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
269 int kidpipe[2];
270 int kidchildpid;
271
272 #define READ 0
273 #define WRITE 1
274
275 ck_pipe (pipe);
276
277 childpid = fork ();
278 if (childpid < 0)
279 {
280 msg_perror ("cannot fork");
281 exit (EX_SYSTEM);
282 }
283 if (childpid > 0)
284 {
285 /* We're the parent. Clean up and be happy */
286 /* This, at least, is easy */
287
288 if (ar_reading)
289 {
290 f_reblock++;
291 archive = pipe[READ];
292 ck_close (pipe[WRITE]);
293 }
294 else
295 {
296 archive = pipe[WRITE];
297 ck_close (pipe[READ]);
298 }
299 return;
300 }
301
302 /* We're the kid */
303 if (ar_reading)
304 {
305 dupto (pipe[WRITE], STDOUT, "(child) pipe to stdout");
306 ck_close (pipe[READ]);
307 }
308 else
309 {
310 dupto (pipe[READ], STDIN, "(child) pipe to stdin");
311 ck_close (pipe[WRITE]);
312 }
313
314 /* We need a child tar only if
315 1: we're reading/writing stdin/out (to force reblocking)
316 2: the file is to be accessed by rmt (compress doesn't know how)
317 3: the file is not a plain file */
318 #ifdef NO_REMOTE
319 if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && isfile (ar_files[0]))
320 #else
321 if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && !_remdev (ar_files[0]) && isfile (ar_files[0]))
322 #endif
323 {
324 /* We don't need a child tar. Open the archive */
325 if (ar_reading)
326 {
327 archive = open (ar_files[0], O_RDONLY | O_BINARY, 0666);
328 if (archive < 0)
329 {
330 msg_perror ("can't open archive %s", ar_files[0]);
331 exit (EX_BADARCH);
332 }
333 dupto (archive, STDIN, "archive to stdin");
334 /* close(archive); */
335 }
336 else
337 {
338 archive = creat (ar_files[0], 0666);
339 if (archive < 0)
340 {
341 msg_perror ("can't open archive %s", ar_files[0]);
342 exit (EX_BADARCH);
343 }
344 dupto (archive, STDOUT, "archive to stdout");
345 /* close(archive); */
346 }
347 }
348 else
349 {
350 /* We need a child tar */
351 ck_pipe (kidpipe);
352
353 kidchildpid = fork ();
354 if (kidchildpid < 0)
355 {
356 msg_perror ("child can't fork");
357 exit (EX_SYSTEM);
358 }
359
360 if (kidchildpid > 0)
361 {
362 /* About to exec compress: set up the files */
363 if (ar_reading)
364 {
365 dupto (kidpipe[READ], STDIN, "((child)) pipe to stdin");
366 ck_close (kidpipe[WRITE]);
367 /* dup2(pipe[WRITE],STDOUT); */
368 }
369 else
370 {
371 /* dup2(pipe[READ],STDIN); */
372 dupto (kidpipe[WRITE], STDOUT, "((child)) pipe to stdout");
373 ck_close (kidpipe[READ]);
374 }
375 /* ck_close(pipe[READ]); */
376 /* ck_close(pipe[WRITE]); */
377 /* ck_close(kidpipe[READ]);
378 ck_close(kidpipe[WRITE]); */
379 }
380 else
381 {
382 /* Grandchild. Do the right thing, namely sit here and
383 read/write the archive, and feed stuff back to compress */
384 tar = "tar (child)";
385 if (ar_reading)
386 {
387 dupto (kidpipe[WRITE], STDOUT, "[child] pipe to stdout");
388 ck_close (kidpipe[READ]);
389 }
390 else
391 {
392 dupto (kidpipe[READ], STDIN, "[child] pipe to stdin");
393 ck_close (kidpipe[WRITE]);
394 }
395
396 if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
397 {
398 if (ar_reading)
399 archive = STDIN;
400 else
401 archive = STDOUT;
402 }
403 else /* This can't happen if (ar_reading==2)
404 archive = rmtopen(ar_files[0], O_RDWR|O_CREAT|O_BINARY, 0666);
405 else */ if (ar_reading)
406 archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
407 else
408 archive = rmtcreat (ar_files[0], 0666);
409
410 if (archive < 0)
411 {
412 msg_perror ("can't open archive %s", ar_files[0]);
413 exit (EX_BADARCH);
414 }
415
416 if (ar_reading)
417 {
418 for (;;)
419 {
420 char *ptr;
421 int max, count;
422
423 r_error_count = 0;
424 error_loop:
425 err = rmtread (archive, ar_block->charptr, (int) (blocksize));
426 if (err < 0)
427 {
428 readerror ();
429 goto error_loop;
430 }
431 if (err == 0)
432 break;
433 ptr = ar_block->charptr;
434 max = err;
435 while (max)
436 {
437 count = (max < RECORDSIZE) ? max : RECORDSIZE;
438 err = write (STDOUT, ptr, count);
439 if (err != count)
440 {
441 if (err < 0)
442 {
443 msg_perror ("can't write to compress");
444 exit (EX_SYSTEM);
445 }
446 else
447 msg ("write to compress short %d bytes", count - err);
448 count = (err < 0) ? 0 : err;
449 }
450 ptr += count;
451 max -= count;
452 }
453 }
454 }
455 else
456 {
457 for (;;)
458 {
459 int n;
460 char *ptr;
461
462 n = blocksize;
463 ptr = ar_block->charptr;
464 while (n)
465 {
466 err = read (STDIN, ptr, (n < RECORDSIZE) ? n : RECORDSIZE);
467 if (err <= 0)
468 break;
469 n -= err;
470 ptr += err;
471 }
472 /* EOF */
473 if (err == 0)
474 {
475 if (f_compress < 2)
476 blocksize -= n;
477 else
478 bzero (ar_block->charptr + blocksize - n, n);
479 err = rmtwrite (archive, ar_block->charptr, blocksize);
480 if (err != (blocksize))
481 writeerror (err);
482 if (f_compress < 2)
483 blocksize += n;
484 break;
485 }
486 if (n)
487 {
488 msg_perror ("can't read from compress");
489 exit (EX_SYSTEM);
490 }
491 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
492 if (err != blocksize)
493 writeerror (err);
494 }
495 }
496
497 /* close_archive(); */
498 exit (0);
499 }
500 }
501 /* So we should exec compress (-d) */
502 if (ar_reading)
503 execlp ("compress", "compress", "-d", (char *) 0);
504 else
505 execlp ("compress", "compress", (char *) 0);
506 msg_perror ("can't exec compress");
507 _exit (EX_SYSTEM);
508 }
509
510
511 /* return non-zero if p is the name of a directory */
512 int
513 isfile (p)
514 char *p;
515 {
516 struct stat stbuf;
517
518 if (stat (p, &stbuf) < 0)
519 return 1;
520 if (S_ISREG (stbuf.st_mode))
521 return 1;
522 return 0;
523 }
524
525 #endif
526
527 /*
528 * Open an archive file. The argument specifies whether we are
529 * reading or writing.
530 */
531 /* JF if the arg is 2, open for reading and writing. */
532 void
533 open_archive (reading)
534 int reading;
535 {
536 msg_file = f_exstdout ? stderr : stdout;
537
538 if (blocksize == 0)
539 {
540 msg ("invalid value for blocksize");
541 exit (EX_ARGSBAD);
542 }
543
544 if (n_ar_files == 0)
545 {
546 msg ("No archive name given, what should I do?");
547 exit (EX_BADARCH);
548 }
549
550 /*NOSTRICT*/
551 if (f_multivol)
552 {
553 ar_block = (union record *) valloc ((unsigned) (blocksize + (2 * RECORDSIZE)));
554 if (ar_block)
555 ar_block += 2;
556 }
557 else
558 ar_block = (union record *) valloc ((unsigned) blocksize);
559 if (!ar_block)
560 {
561 msg ("could not allocate memory for blocking factor %d",
562 blocking);
563 exit (EX_ARGSBAD);
564 }
565
566 ar_record = ar_block;
567 ar_last = ar_block + blocking;
568 ar_reading = reading;
569
570 if (f_multivol && f_verify)
571 {
572 msg ("cannot verify multi-volume archives");
573 exit (EX_ARGSBAD);
574 }
575
576 if (f_compress)
577 {
578 if (reading == 2 || f_verify)
579 {
580 msg ("cannot update or verify compressed archives");
581 exit (EX_ARGSBAD);
582 }
583 if (f_multivol)
584 {
585 msg ("cannot use multi-volume compressed archives");
586 exit (EX_ARGSBAD);
587 }
588 child_open ();
589 if (!reading && ar_files[0][0] == '-' && ar_files[0][1] == '\0')
590 msg_file = stderr;
591 /* child_open(rem_host, rem_file); */
592 }
593 else if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
594 {
595 f_reblock++; /* Could be a pipe, be safe */
596 if (f_verify)
597 {
598 msg ("can't verify stdin/stdout archive");
599 exit (EX_ARGSBAD);
600 }
601 if (reading == 2)
602 {
603 archive = STDIN;
604 msg_file = stderr;
605 write_archive_to_stdout++;
606 }
607 else if (reading)
608 archive = STDIN;
609 else
610 {
611 archive = STDOUT;
612 msg_file = stderr;
613 }
614 }
615 else if (reading == 2 || f_verify)
616 {
617 archive = rmtopen (ar_files[0], O_RDWR | O_CREAT | O_BINARY, 0666);
618 }
619 else if (reading)
620 {
621 archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
622 }
623 else
624 {
625 archive = rmtcreat (ar_files[0], 0666);
626 }
627 if (archive < 0)
628 {
629 msg_perror ("can't open %s", ar_files[0]);
630 exit (EX_BADARCH);
631 }
632 #ifndef __MSDOS__
633 if (!_isrmt (archive))
634 {
635 struct stat tmp_stat;
636
637 fstat (archive, &tmp_stat);
638 if (S_ISREG (tmp_stat.st_mode))
639 {
640 ar_dev = tmp_stat.st_dev;
641 ar_ino = tmp_stat.st_ino;
642 }
643 }
644 #endif
645
646 #ifdef __MSDOS__
647 setmode (archive, O_BINARY);
648 #endif
649
650 if (reading)
651 {
652 ar_last = ar_block; /* Set up for 1st block = # 0 */
653 (void) findrec (); /* Read it in, check for EOF */
654
655 if (f_volhdr)
656 {
657 union record *head;
658 #if 0
659 char *ptr;
660
661 if (f_multivol)
662 {
663 ptr = malloc (strlen (f_volhdr) + 20);
664 sprintf (ptr, "%s Volume %d", f_volhdr, 1);
665 }
666 else
667 ptr = f_volhdr;
668 #endif
669 head = findrec ();
670 if (!head)
671 {
672 msg ("Archive not labelled to match %s", f_volhdr);
673 exit (EX_BADVOL);
674 }
675 if (re_match (label_pattern, head->header.arch_name,
676 strlen (head->header.arch_name), 0, 0) < 0)
677 {
678 msg ("Volume mismatch! %s!=%s", f_volhdr,
679 head->header.arch_name);
680 exit (EX_BADVOL);
681 }
682 #if 0
683 if (strcmp (ptr, head->header.name))
684 {
685 msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
686 exit (EX_BADVOL);
687 }
688 if (ptr != f_volhdr)
689 free (ptr);
690 #endif
691 }
692 }
693 else if (f_volhdr)
694 {
695 bzero ((void *) ar_block, RECORDSIZE);
696 if (f_multivol)
697 sprintf (ar_block->header.arch_name, "%s Volume 1", f_volhdr);
698 else
699 strcpy (ar_block->header.arch_name, f_volhdr);
700 ar_block->header.linkflag = LF_VOLHDR;
701 to_oct (time (0), 1 + 12, ar_block->header.mtime);
702 finish_header (ar_block);
703 /* ar_record++; */
704 }
705 }
706
707
708 /*
709 * Remember a union record * as pointing to something that we
710 * need to keep when reading onward in the file. Only one such
711 * thing can be remembered at once, and it only works when reading
712 * an archive.
713 *
714 * We calculate "offset" then add it because some compilers end up
715 * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
716 * subtracting ar_block from that, shifting it back, losing the top 9 bits.
717 */
718 void
719 saverec (pointer)
720 union record **pointer;
721 {
722 long offset;
723
724 save_rec = pointer;
725 offset = ar_record - ar_block;
726 saved_recno = baserec + offset;
727 }
728
729 /*
730 * Perform a write to flush the buffer.
731 */
732
733 /*send_buffer_to_file();
734 if(new_volume) {
735 deal_with_new_volume_stuff();
736 send_buffer_to_file();
737 }
738 */
739
740 void
741 fl_write ()
742 {
743 int err;
744 int copy_back;
745 static long bytes_written = 0;
746
747 if (f_checkpoint && !(++checkpoint % 10))
748 msg ("Write checkpoint %d\n", checkpoint);
749 if (tape_length && bytes_written >= tape_length * 1024)
750 {
751 errno = ENOSPC;
752 err = 0;
753 }
754 else
755 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
756 if (err != blocksize && !f_multivol)
757 writeerror (err);
758 else if (f_totals)
759 tot_written += blocksize;
760
761 if (err > 0)
762 bytes_written += err;
763 if (err == blocksize)
764 {
765 if (f_multivol)
766 {
767 if (!save_name)
768 {
769 real_s_name[0] = '\0';
770 real_s_totsize = 0;
771 real_s_sizeleft = 0;
772 return;
773 }
774 #ifdef __MSDOS__
775 if (save_name[1] == ':')
776 save_name += 2;
777 #endif
778 while (*save_name == '/')
779 save_name++;
780
781 strcpy (real_s_name, save_name);
782 real_s_totsize = save_totsize;
783 real_s_sizeleft = save_sizeleft;
784 }
785 return;
786 }
787
788 /* We're multivol Panic if we didn't get the right kind of response */
789 /* ENXIO is for the UNIX PC */
790 if (err < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
791 writeerror (err);
792
793 /* If error indicates a short write, we just move to the next tape. */
794
795 if (new_volume (0) < 0)
796 return;
797 bytes_written = 0;
798 if (f_volhdr && real_s_name[0])
799 {
800 copy_back = 2;
801 ar_block -= 2;
802 }
803 else if (f_volhdr || real_s_name[0])
804 {
805 copy_back = 1;
806 ar_block--;
807 }
808 else
809 copy_back = 0;
810 if (f_volhdr)
811 {
812 bzero ((void *) ar_block, RECORDSIZE);
813 sprintf (ar_block->header.arch_name, "%s Volume %d", f_volhdr, volno);
814 to_oct (time (0), 1 + 12, ar_block->header.mtime);
815 ar_block->header.linkflag = LF_VOLHDR;
816 finish_header (ar_block);
817 }
818 if (real_s_name[0])
819 {
820 int tmp;
821
822 if (f_volhdr)
823 ar_block++;
824 bzero ((void *) ar_block, RECORDSIZE);
825 strcpy (ar_block->header.arch_name, real_s_name);
826 ar_block->header.linkflag = LF_MULTIVOL;
827 to_oct ((long) real_s_sizeleft, 1 + 12,
828 ar_block->header.size);
829 to_oct ((long) real_s_totsize - real_s_sizeleft,
830 1 + 12, ar_block->header.offset);
831 tmp = f_verbose;
832 f_verbose = 0;
833 finish_header (ar_block);
834 f_verbose = tmp;
835 if (f_volhdr)
836 ar_block--;
837 }
838
839 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
840 if (err != blocksize)
841 writeerror (err);
842 else if (f_totals)
843 tot_written += blocksize;
844
845
846 bytes_written = blocksize;
847 if (copy_back)
848 {
849 ar_block += copy_back;
850 bcopy ((void *) (ar_block + blocking - copy_back),
851 (void *) ar_record,
852 copy_back * RECORDSIZE);
853 ar_record += copy_back;
854
855 if (real_s_sizeleft >= copy_back * RECORDSIZE)
856 real_s_sizeleft -= copy_back * RECORDSIZE;
857 else if ((real_s_sizeleft + RECORDSIZE - 1) / RECORDSIZE <= copy_back)
858 real_s_name[0] = '\0';
859 else
860 {
861 #ifdef __MSDOS__
862 if (save_name[1] == ':')
863 save_name += 2;
864 #endif
865 while (*save_name == '/')
866 save_name++;
867
868 strcpy (real_s_name, save_name);
869 real_s_sizeleft = save_sizeleft;
870 real_s_totsize = save_totsize;
871 }
872 copy_back = 0;
873 }
874 }
875
876 /* Handle write errors on the archive. Write errors are always fatal */
877 /* Hitting the end of a volume does not cause a write error unless the write
878 * was the first block of the volume */
879
880 void
881 writeerror (err)
882 int err;
883 {
884 if (err < 0)
885 {
886 msg_perror ("can't write to %s", ar_files[cur_ar_file]);
887 exit (EX_BADARCH);
888 }
889 else
890 {
891 msg ("only wrote %u of %u bytes to %s", err, blocksize, ar_files[cur_ar_file]);
892 exit (EX_BADARCH);
893 }
894 }
895
896 /*
897 * Handle read errors on the archive.
898 *
899 * If the read should be retried, readerror() returns to the caller.
900 */
901 void
902 readerror ()
903 {
904 # define READ_ERROR_MAX 10
905
906 read_error_flag++; /* Tell callers */
907
908 msg_perror ("read error on %s", ar_files[cur_ar_file]);
909
910 if (baserec == 0)
911 {
912 /* First block of tape. Probably stupidity error */
913 exit (EX_BADARCH);
914 }
915
916 /*
917 * Read error in mid archive. We retry up to READ_ERROR_MAX times
918 * and then give up on reading the archive. We set read_error_flag
919 * for our callers, so they can cope if they want.
920 */
921 if (r_error_count++ > READ_ERROR_MAX)
922 {
923 msg ("Too many errors, quitting.");
924 exit (EX_BADARCH);
925 }
926 return;
927 }
928
929
930 /*
931 * Perform a read to flush the buffer.
932 */
933 void
934 fl_read ()
935 {
936 int err; /* Result from system call */
937 int left; /* Bytes left */
938 char *more; /* Pointer to next byte to read */
939
940 if (f_checkpoint && !(++checkpoint % 10))
941 msg ("Read checkpoint %d\n", checkpoint);
942
943 /*
944 * Clear the count of errors. This only applies to a single
945 * call to fl_read. We leave read_error_flag alone; it is
946 * only turned off by higher level software.
947 */
948 r_error_count = 0; /* Clear error count */
949
950 /*
951 * If we are about to wipe out a record that
952 * somebody needs to keep, copy it out to a holding
953 * area and adjust somebody's pointer to it.
954 */
955 if (save_rec &&
956 *save_rec >= ar_record &&
957 *save_rec < ar_last)
958 {
959 record_save_area = **save_rec;
960 *save_rec = &record_save_area;
961 }
962 if (write_archive_to_stdout && baserec != 0)
963 {
964 err = rmtwrite (1, ar_block->charptr, blocksize);
965 if (err != blocksize)
966 writeerror (err);
967 }
968 if (f_multivol)
969 {
970 if (save_name)
971 {
972 if (save_name != real_s_name)
973 {
974 #ifdef __MSDOS__
975 if (save_name[1] == ':')
976 save_name += 2;
977 #endif
978 while (*save_name == '/')
979 save_name++;
980
981 strcpy (real_s_name, save_name);
982 save_name = real_s_name;
983 }
984 real_s_totsize = save_totsize;
985 real_s_sizeleft = save_sizeleft;
986
987 }
988 else
989 {
990 real_s_name[0] = '\0';
991 real_s_totsize = 0;
992 real_s_sizeleft = 0;
993 }
994 }
995
996 error_loop:
997 err = rmtread (archive, ar_block->charptr, (int) blocksize);
998 if (err == blocksize)
999 return;
1000
1001 if ((err == 0 || (err < 0 && errno == ENOSPC) || (err > 0 && !f_reblock)) && f_multivol)
1002 {
1003 union record *head;
1004
1005 try_volume:
1006 if (new_volume ((cmd_mode == CMD_APPEND || cmd_mode == CMD_CAT || cmd_mode == CMD_UPDATE) ? 2 : 1) < 0)
1007 return;
1008 vol_error:
1009 err = rmtread (archive, ar_block->charptr, (int) blocksize);
1010 if (err < 0)
1011 {
1012 readerror ();
1013 goto vol_error;
1014 }
1015 if (err != blocksize)
1016 goto short_read;
1017
1018 head = ar_block;
1019
1020 if (head->header.linkflag == LF_VOLHDR)
1021 {
1022 if (f_volhdr)
1023 {
1024 #if 0
1025 char *ptr;
1026
1027 ptr = (char *) malloc (strlen (f_volhdr) + 20);
1028 sprintf (ptr, "%s Volume %d", f_volhdr, volno);
1029 #endif
1030 if (re_match (label_pattern, head->header.arch_name,
1031 strlen (head->header.arch_name),
1032 0, 0) < 0)
1033 {
1034 msg ("Volume mismatch! %s!=%s", f_volhdr,
1035 head->header.arch_name);
1036 --volno;
1037 --global_volno;
1038 goto try_volume;
1039 }
1040
1041 #if 0
1042 if (strcmp (ptr, head->header.name))
1043 {
1044 msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
1045 --volno;
1046 --global_volno;
1047 free (ptr);
1048 goto try_volume;
1049 }
1050 free (ptr);
1051 #endif
1052 }
1053 if (f_verbose)
1054 fprintf (msg_file, "Reading %s\n", head->header.arch_name);
1055 head++;
1056 }
1057 else if (f_volhdr)
1058 {
1059 msg ("Warning: No volume header!");
1060 }
1061
1062 if (real_s_name[0])
1063 {
1064 long from_oct ();
1065
1066 if (head->header.linkflag != LF_MULTIVOL || strcmp (head->header.arch_name, real_s_name))
1067 {
1068 msg ("%s is not continued on this volume!", real_s_name);
1069 --volno;
1070 --global_volno;
1071 goto try_volume;
1072 }
1073 if (real_s_totsize != from_oct (1 + 12, head->header.size) + from_oct (1 + 12, head->header.offset))
1074 {
1075 msg ("%s is the wrong size (%ld!=%ld+%ld)",
1076 head->header.arch_name, save_totsize,
1077 from_oct (1 + 12, head->header.size),
1078 from_oct (1 + 12, head->header.offset));
1079 --volno;
1080 --global_volno;
1081 goto try_volume;
1082 }
1083 if (real_s_totsize - real_s_sizeleft != from_oct (1 + 12, head->header.offset))
1084 {
1085 msg ("This volume is out of sequence");
1086 --volno;
1087 --global_volno;
1088 goto try_volume;
1089 }
1090 head++;
1091 }
1092 ar_record = head;
1093 return;
1094 }
1095 else if (err < 0)
1096 {
1097 readerror ();
1098 goto error_loop; /* Try again */
1099 }
1100
1101 short_read:
1102 more = ar_block->charptr + err;
1103 left = blocksize - err;
1104
1105 again:
1106 if (0 == (((unsigned) left) % RECORDSIZE))
1107 {
1108 /* FIXME, for size=0, multi vol support */
1109 /* On the first block, warn about the problem */
1110 if (!f_reblock && baserec == 0 && f_verbose && err > 0)
1111 {
1112 /* msg("Blocksize = %d record%s",
1113 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
1114 msg ("Blocksize = %d records", err / RECORDSIZE);
1115 }
1116 ar_last = ar_block + ((unsigned) (blocksize - left)) / RECORDSIZE;
1117 return;
1118 }
1119 if (f_reblock)
1120 {
1121 /*
1122 * User warned us about this. Fix up.
1123 */
1124 if (left > 0)
1125 {
1126 error2loop:
1127 err = rmtread (archive, more, (int) left);
1128 if (err < 0)
1129 {
1130 readerror ();
1131 goto error2loop; /* Try again */
1132 }
1133 if (err == 0)
1134 {
1135 msg ("archive %s EOF not on block boundary", ar_files[cur_ar_file]);
1136 exit (EX_BADARCH);
1137 }
1138 left -= err;
1139 more += err;
1140 goto again;
1141 }
1142 }
1143 else
1144 {
1145 msg ("only read %d bytes from archive %s", err, ar_files[cur_ar_file]);
1146 exit (EX_BADARCH);
1147 }
1148 }
1149
1150
1151 /*
1152 * Flush the current buffer to/from the archive.
1153 */
1154 void
1155 flush_archive ()
1156 {
1157 int c;
1158
1159 baserec += ar_last - ar_block;/* Keep track of block #s */
1160 ar_record = ar_block; /* Restore pointer to start */
1161 ar_last = ar_block + blocking;/* Restore pointer to end */
1162
1163 if (ar_reading)
1164 {
1165 if (time_to_start_writing)
1166 {
1167 time_to_start_writing = 0;
1168 ar_reading = 0;
1169
1170 if (file_to_switch_to >= 0)
1171 {
1172 if ((c = rmtclose (archive)) < 0)
1173 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1174
1175 archive = file_to_switch_to;
1176 }
1177 else
1178 (void) backspace_output ();
1179 fl_write ();
1180 }
1181 else
1182 fl_read ();
1183 }
1184 else
1185 {
1186 fl_write ();
1187 }
1188 }
1189
1190 /* Backspace the archive descriptor by one blocks worth.
1191 If its a tape, MTIOCTOP will work. If its something else,
1192 we try to seek on it. If we can't seek, we lose! */
1193 int
1194 backspace_output ()
1195 {
1196 long cur;
1197 /* int er; */
1198 extern char *output_start;
1199
1200 #ifdef MTIOCTOP
1201 struct mtop t;
1202
1203 t.mt_op = MTBSR;
1204 t.mt_count = 1;
1205 if ((rmtioctl (archive, MTIOCTOP, &t)) >= 0)
1206 return 1;
1207 if (errno == EIO && (rmtioctl (archive, MTIOCTOP, &t)) >= 0)
1208 return 1;
1209 #endif
1210
1211 cur = rmtlseek (archive, 0L, 1);
1212 cur -= blocksize;
1213 /* Seek back to the beginning of this block and
1214 start writing there. */
1215
1216 if (rmtlseek (archive, cur, 0) != cur)
1217 {
1218 /* Lseek failed. Try a different method */
1219 msg ("Couldn't backspace archive file. It may be unreadable without -i.");
1220 /* Replace the first part of the block with nulls */
1221 if (ar_block->charptr != output_start)
1222 bzero (ar_block->charptr, output_start - ar_block->charptr);
1223 return 2;
1224 }
1225 return 3;
1226 }
1227
1228
1229 /*
1230 * Close the archive file.
1231 */
1232 void
1233 close_archive ()
1234 {
1235 int child;
1236 int status;
1237 int c;
1238
1239 if (time_to_start_writing || !ar_reading)
1240 flush_archive ();
1241 if (cmd_mode == CMD_DELETE)
1242 {
1243 off_t pos;
1244
1245 pos = rmtlseek (archive, 0L, 1);
1246 #ifndef __MSDOS__
1247 (void) ftruncate (archive, pos);
1248 #else
1249 (void) rmtwrite (archive, "", 0);
1250 #endif
1251 }
1252 if (f_verify)
1253 verify_volume ();
1254
1255 if ((c = rmtclose (archive)) < 0)
1256 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1257
1258 #ifndef __MSDOS__
1259 if (childpid)
1260 {
1261 /*
1262 * Loop waiting for the right child to die, or for
1263 * no more kids.
1264 */
1265 while (((child = wait (&status)) != childpid) && child != -1)
1266 ;
1267
1268 if (child != -1)
1269 {
1270 if (WIFSIGNALED (status))
1271 {
1272 /* SIGPIPE is OK, everything else is a problem. */
1273 if (WTERMSIG (status) != SIGPIPE)
1274 msg ("child died with signal %d%s", WTERMSIG (status),
1275 WIFCOREDUMPED (status) ? " (core dumped)" : "");
1276 }
1277 else
1278 {
1279 /* Child voluntarily terminated -- but why? */
1280 if (WEXITSTATUS (status) == MAGIC_STAT)
1281 {
1282 exit (EX_SYSTEM); /* Child had trouble */
1283 }
1284 if (WEXITSTATUS (status) == (SIGPIPE + 128))
1285 {
1286 /*
1287 * /bin/sh returns this if its child
1288 * dies with SIGPIPE. 'Sok.
1289 */
1290 /* Do nothing. */
1291 }
1292 else if (WEXITSTATUS (status))
1293 msg ("child returned status %d",
1294 WEXITSTATUS (status));
1295 }
1296 }
1297 }
1298 #endif /* __MSDOS__ */
1299 }
1300
1301
1302 #ifdef DONTDEF
1303 /*
1304 * Message management.
1305 *
1306 * anno writes a message prefix on stream (eg stdout, stderr).
1307 *
1308 * The specified prefix is normally output followed by a colon and a space.
1309 * However, if other command line options are set, more output can come
1310 * out, such as the record # within the archive.
1311 *
1312 * If the specified prefix is NULL, no output is produced unless the
1313 * command line option(s) are set.
1314 *
1315 * If the third argument is 1, the "saved" record # is used; if 0, the
1316 * "current" record # is used.
1317 */
1318 void
1319 anno (stream, prefix, savedp)
1320 FILE *stream;
1321 char *prefix;
1322 int savedp;
1323 {
1324 # define MAXANNO 50
1325 char buffer[MAXANNO]; /* Holds annorecment */
1326 # define ANNOWIDTH 13
1327 int space;
1328 long offset;
1329 int save_e;
1330
1331 save_e = errno;
1332 /* Make sure previous output gets out in sequence */
1333 if (stream == stderr)
1334 fflush (stdout);
1335 if (f_sayblock)
1336 {
1337 if (prefix)
1338 {
1339 fputs (prefix, stream);
1340 putc (' ', stream);
1341 }
1342 offset = ar_record - ar_block;
1343 (void) sprintf (buffer, "rec %d: ",
1344 savedp ? saved_recno :
1345 baserec + offset);
1346 fputs (buffer, stream);
1347 space = ANNOWIDTH - strlen (buffer);
1348 if (space > 0)
1349 {
1350 fprintf (stream, "%*s", space, "");
1351 }
1352 }
1353 else if (prefix)
1354 {
1355 fputs (prefix, stream);
1356 fputs (": ", stream);
1357 }
1358 errno = save_e;
1359 }
1360
1361 #endif
1362
1363 /* Called to initialize the global volume number. */
1364 void
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 void
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.100209 seconds and 5 git commands to generate.