]> 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, 1993 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 compression program");
444 exit (EX_SYSTEM);
445 }
446 else
447 msg ("write to compression program short %d bytes",
448 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_block)
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_block)
484 blocksize += n;
485 break;
486 }
487 if (n)
488 {
489 msg_perror ("can't read from compression program");
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 (f_compressprog, f_compressprog, "-d", (char *) 0);
505 else
506 execlp (f_compressprog, f_compressprog, (char *) 0);
507 msg_perror ("can't exec %s", f_compressprog);
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_compressprog)
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 current_file_name = ar_block->header.arch_name;
702 ar_block->header.linkflag = LF_VOLHDR;
703 to_oct (time (0), 1 + 12, ar_block->header.mtime);
704 finish_header (ar_block);
705 /* ar_record++; */
706 }
707 }
708
709
710 /*
711 * Remember a union record * as pointing to something that we
712 * need to keep when reading onward in the file. Only one such
713 * thing can be remembered at once, and it only works when reading
714 * an archive.
715 *
716 * We calculate "offset" then add it because some compilers end up
717 * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
718 * subtracting ar_block from that, shifting it back, losing the top 9 bits.
719 */
720 void
721 saverec (pointer)
722 union record **pointer;
723 {
724 long offset;
725
726 save_rec = pointer;
727 offset = ar_record - ar_block;
728 saved_recno = baserec + offset;
729 }
730
731 /*
732 * Perform a write to flush the buffer.
733 */
734
735 /*send_buffer_to_file();
736 if(new_volume) {
737 deal_with_new_volume_stuff();
738 send_buffer_to_file();
739 }
740 */
741
742 void
743 fl_write ()
744 {
745 int err;
746 int copy_back;
747 static long bytes_written = 0;
748
749 if (f_checkpoint && !(++checkpoint % 10))
750 msg ("Write checkpoint %d\n", checkpoint);
751 if (tape_length && bytes_written >= tape_length * 1024)
752 {
753 errno = ENOSPC;
754 err = 0;
755 }
756 else
757 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
758 if (err != blocksize && !f_multivol)
759 writeerror (err);
760 else if (f_totals)
761 tot_written += blocksize;
762
763 if (err > 0)
764 bytes_written += err;
765 if (err == blocksize)
766 {
767 if (f_multivol)
768 {
769 if (!save_name)
770 {
771 real_s_name[0] = '\0';
772 real_s_totsize = 0;
773 real_s_sizeleft = 0;
774 return;
775 }
776 #ifdef __MSDOS__
777 if (save_name[1] == ':')
778 save_name += 2;
779 #endif
780 while (*save_name == '/')
781 save_name++;
782
783 strcpy (real_s_name, save_name);
784 real_s_totsize = save_totsize;
785 real_s_sizeleft = save_sizeleft;
786 }
787 return;
788 }
789
790 /* We're multivol Panic if we didn't get the right kind of response */
791 /* ENXIO is for the UNIX PC */
792 if (err < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
793 writeerror (err);
794
795 /* If error indicates a short write, we just move to the next tape. */
796
797 if (new_volume (0) < 0)
798 return;
799 bytes_written = 0;
800 if (f_volhdr && real_s_name[0])
801 {
802 copy_back = 2;
803 ar_block -= 2;
804 }
805 else if (f_volhdr || real_s_name[0])
806 {
807 copy_back = 1;
808 ar_block--;
809 }
810 else
811 copy_back = 0;
812 if (f_volhdr)
813 {
814 bzero ((void *) ar_block, RECORDSIZE);
815 sprintf (ar_block->header.arch_name, "%s Volume %d", f_volhdr, volno);
816 to_oct (time (0), 1 + 12, ar_block->header.mtime);
817 ar_block->header.linkflag = LF_VOLHDR;
818 finish_header (ar_block);
819 }
820 if (real_s_name[0])
821 {
822 int tmp;
823
824 if (f_volhdr)
825 ar_block++;
826 bzero ((void *) ar_block, RECORDSIZE);
827 strcpy (ar_block->header.arch_name, real_s_name);
828 ar_block->header.linkflag = LF_MULTIVOL;
829 to_oct ((long) real_s_sizeleft, 1 + 12,
830 ar_block->header.size);
831 to_oct ((long) real_s_totsize - real_s_sizeleft,
832 1 + 12, ar_block->header.offset);
833 tmp = f_verbose;
834 f_verbose = 0;
835 finish_header (ar_block);
836 f_verbose = tmp;
837 if (f_volhdr)
838 ar_block--;
839 }
840
841 err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
842 if (err != blocksize)
843 writeerror (err);
844 else if (f_totals)
845 tot_written += blocksize;
846
847
848 bytes_written = blocksize;
849 if (copy_back)
850 {
851 ar_block += copy_back;
852 bcopy ((void *) (ar_block + blocking - copy_back),
853 (void *) ar_record,
854 copy_back * RECORDSIZE);
855 ar_record += copy_back;
856
857 if (real_s_sizeleft >= copy_back * RECORDSIZE)
858 real_s_sizeleft -= copy_back * RECORDSIZE;
859 else if ((real_s_sizeleft + RECORDSIZE - 1) / RECORDSIZE <= copy_back)
860 real_s_name[0] = '\0';
861 else
862 {
863 #ifdef __MSDOS__
864 if (save_name[1] == ':')
865 save_name += 2;
866 #endif
867 while (*save_name == '/')
868 save_name++;
869
870 strcpy (real_s_name, save_name);
871 real_s_sizeleft = save_sizeleft;
872 real_s_totsize = save_totsize;
873 }
874 copy_back = 0;
875 }
876 }
877
878 /* Handle write errors on the archive. Write errors are always fatal */
879 /* Hitting the end of a volume does not cause a write error unless the write
880 * was the first block of the volume */
881
882 void
883 writeerror (err)
884 int err;
885 {
886 if (err < 0)
887 {
888 msg_perror ("can't write to %s", ar_files[cur_ar_file]);
889 exit (EX_BADARCH);
890 }
891 else
892 {
893 msg ("only wrote %u of %u bytes to %s", err, blocksize, ar_files[cur_ar_file]);
894 exit (EX_BADARCH);
895 }
896 }
897
898 /*
899 * Handle read errors on the archive.
900 *
901 * If the read should be retried, readerror() returns to the caller.
902 */
903 void
904 readerror ()
905 {
906 # define READ_ERROR_MAX 10
907
908 read_error_flag++; /* Tell callers */
909
910 msg_perror ("read error on %s", ar_files[cur_ar_file]);
911
912 if (baserec == 0)
913 {
914 /* First block of tape. Probably stupidity error */
915 exit (EX_BADARCH);
916 }
917
918 /*
919 * Read error in mid archive. We retry up to READ_ERROR_MAX times
920 * and then give up on reading the archive. We set read_error_flag
921 * for our callers, so they can cope if they want.
922 */
923 if (r_error_count++ > READ_ERROR_MAX)
924 {
925 msg ("Too many errors, quitting.");
926 exit (EX_BADARCH);
927 }
928 return;
929 }
930
931
932 /*
933 * Perform a read to flush the buffer.
934 */
935 void
936 fl_read ()
937 {
938 int err; /* Result from system call */
939 int left; /* Bytes left */
940 char *more; /* Pointer to next byte to read */
941
942 if (f_checkpoint && !(++checkpoint % 10))
943 msg ("Read checkpoint %d\n", checkpoint);
944
945 /*
946 * Clear the count of errors. This only applies to a single
947 * call to fl_read. We leave read_error_flag alone; it is
948 * only turned off by higher level software.
949 */
950 r_error_count = 0; /* Clear error count */
951
952 /*
953 * If we are about to wipe out a record that
954 * somebody needs to keep, copy it out to a holding
955 * area and adjust somebody's pointer to it.
956 */
957 if (save_rec &&
958 *save_rec >= ar_record &&
959 *save_rec < ar_last)
960 {
961 record_save_area = **save_rec;
962 *save_rec = &record_save_area;
963 }
964 if (write_archive_to_stdout && baserec != 0)
965 {
966 err = rmtwrite (1, ar_block->charptr, blocksize);
967 if (err != blocksize)
968 writeerror (err);
969 }
970 if (f_multivol)
971 {
972 if (save_name)
973 {
974 if (save_name != real_s_name)
975 {
976 #ifdef __MSDOS__
977 if (save_name[1] == ':')
978 save_name += 2;
979 #endif
980 while (*save_name == '/')
981 save_name++;
982
983 strcpy (real_s_name, save_name);
984 save_name = real_s_name;
985 }
986 real_s_totsize = save_totsize;
987 real_s_sizeleft = save_sizeleft;
988
989 }
990 else
991 {
992 real_s_name[0] = '\0';
993 real_s_totsize = 0;
994 real_s_sizeleft = 0;
995 }
996 }
997
998 error_loop:
999 err = rmtread (archive, ar_block->charptr, (int) blocksize);
1000 if (err == blocksize)
1001 return;
1002
1003 if ((err == 0 || (err < 0 && errno == ENOSPC) || (err > 0 && !f_reblock)) && f_multivol)
1004 {
1005 union record *head;
1006
1007 try_volume:
1008 if (new_volume ((cmd_mode == CMD_APPEND || cmd_mode == CMD_CAT || cmd_mode == CMD_UPDATE) ? 2 : 1) < 0)
1009 return;
1010 vol_error:
1011 err = rmtread (archive, ar_block->charptr, (int) blocksize);
1012 if (err < 0)
1013 {
1014 readerror ();
1015 goto vol_error;
1016 }
1017 if (err != blocksize)
1018 goto short_read;
1019
1020 head = ar_block;
1021
1022 if (head->header.linkflag == LF_VOLHDR)
1023 {
1024 if (f_volhdr)
1025 {
1026 #if 0
1027 char *ptr;
1028
1029 ptr = (char *) malloc (strlen (f_volhdr) + 20);
1030 sprintf (ptr, "%s Volume %d", f_volhdr, volno);
1031 #endif
1032 if (re_match (label_pattern, head->header.arch_name,
1033 strlen (head->header.arch_name),
1034 0, 0) < 0)
1035 {
1036 msg ("Volume mismatch! %s!=%s", f_volhdr,
1037 head->header.arch_name);
1038 --volno;
1039 --global_volno;
1040 goto try_volume;
1041 }
1042
1043 #if 0
1044 if (strcmp (ptr, head->header.name))
1045 {
1046 msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
1047 --volno;
1048 --global_volno;
1049 free (ptr);
1050 goto try_volume;
1051 }
1052 free (ptr);
1053 #endif
1054 }
1055 if (f_verbose)
1056 fprintf (msg_file, "Reading %s\n", head->header.arch_name);
1057 head++;
1058 }
1059 else if (f_volhdr)
1060 {
1061 msg ("Warning: No volume header!");
1062 }
1063
1064 if (real_s_name[0])
1065 {
1066 long from_oct ();
1067
1068 if (head->header.linkflag != LF_MULTIVOL || strcmp (head->header.arch_name, real_s_name))
1069 {
1070 msg ("%s is not continued on this volume!", real_s_name);
1071 --volno;
1072 --global_volno;
1073 goto try_volume;
1074 }
1075 if (real_s_totsize != from_oct (1 + 12, head->header.size) + from_oct (1 + 12, head->header.offset))
1076 {
1077 msg ("%s is the wrong size (%ld!=%ld+%ld)",
1078 head->header.arch_name, save_totsize,
1079 from_oct (1 + 12, head->header.size),
1080 from_oct (1 + 12, head->header.offset));
1081 --volno;
1082 --global_volno;
1083 goto try_volume;
1084 }
1085 if (real_s_totsize - real_s_sizeleft != from_oct (1 + 12, head->header.offset))
1086 {
1087 msg ("This volume is out of sequence");
1088 --volno;
1089 --global_volno;
1090 goto try_volume;
1091 }
1092 head++;
1093 }
1094 ar_record = head;
1095 return;
1096 }
1097 else if (err < 0)
1098 {
1099 readerror ();
1100 goto error_loop; /* Try again */
1101 }
1102
1103 short_read:
1104 more = ar_block->charptr + err;
1105 left = blocksize - err;
1106
1107 again:
1108 if (0 == (((unsigned) left) % RECORDSIZE))
1109 {
1110 /* FIXME, for size=0, multi vol support */
1111 /* On the first block, warn about the problem */
1112 if (!f_reblock && baserec == 0 && f_verbose && err > 0)
1113 {
1114 /* msg("Blocksize = %d record%s",
1115 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
1116 msg ("Blocksize = %d records", err / RECORDSIZE);
1117 }
1118 ar_last = ar_block + ((unsigned) (blocksize - left)) / RECORDSIZE;
1119 return;
1120 }
1121 if (f_reblock)
1122 {
1123 /*
1124 * User warned us about this. Fix up.
1125 */
1126 if (left > 0)
1127 {
1128 error2loop:
1129 err = rmtread (archive, more, (int) left);
1130 if (err < 0)
1131 {
1132 readerror ();
1133 goto error2loop; /* Try again */
1134 }
1135 if (err == 0)
1136 {
1137 msg ("archive %s EOF not on block boundary", ar_files[cur_ar_file]);
1138 exit (EX_BADARCH);
1139 }
1140 left -= err;
1141 more += err;
1142 goto again;
1143 }
1144 }
1145 else
1146 {
1147 msg ("only read %d bytes from archive %s", err, ar_files[cur_ar_file]);
1148 exit (EX_BADARCH);
1149 }
1150 }
1151
1152
1153 /*
1154 * Flush the current buffer to/from the archive.
1155 */
1156 void
1157 flush_archive ()
1158 {
1159 int c;
1160
1161 baserec += ar_last - ar_block;/* Keep track of block #s */
1162 ar_record = ar_block; /* Restore pointer to start */
1163 ar_last = ar_block + blocking;/* Restore pointer to end */
1164
1165 if (ar_reading)
1166 {
1167 if (time_to_start_writing)
1168 {
1169 time_to_start_writing = 0;
1170 ar_reading = 0;
1171
1172 if (file_to_switch_to >= 0)
1173 {
1174 if ((c = rmtclose (archive)) < 0)
1175 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1176
1177 archive = file_to_switch_to;
1178 }
1179 else
1180 (void) backspace_output ();
1181 fl_write ();
1182 }
1183 else
1184 fl_read ();
1185 }
1186 else
1187 {
1188 fl_write ();
1189 }
1190 }
1191
1192 /* Backspace the archive descriptor by one blocks worth.
1193 If its a tape, MTIOCTOP will work. If its something else,
1194 we try to seek on it. If we can't seek, we lose! */
1195 int
1196 backspace_output ()
1197 {
1198 long cur;
1199 /* int er; */
1200 extern char *output_start;
1201
1202 #ifdef MTIOCTOP
1203 struct mtop t;
1204
1205 t.mt_op = MTBSR;
1206 t.mt_count = 1;
1207 if ((rmtioctl (archive, MTIOCTOP, &t)) >= 0)
1208 return 1;
1209 if (errno == EIO && (rmtioctl (archive, MTIOCTOP, &t)) >= 0)
1210 return 1;
1211 #endif
1212
1213 cur = rmtlseek (archive, 0L, 1);
1214 cur -= blocksize;
1215 /* Seek back to the beginning of this block and
1216 start writing there. */
1217
1218 if (rmtlseek (archive, cur, 0) != cur)
1219 {
1220 /* Lseek failed. Try a different method */
1221 msg ("Couldn't backspace archive file. It may be unreadable without -i.");
1222 /* Replace the first part of the block with nulls */
1223 if (ar_block->charptr != output_start)
1224 bzero (ar_block->charptr, output_start - ar_block->charptr);
1225 return 2;
1226 }
1227 return 3;
1228 }
1229
1230
1231 /*
1232 * Close the archive file.
1233 */
1234 void
1235 close_archive ()
1236 {
1237 int child;
1238 int status;
1239 int c;
1240
1241 if (time_to_start_writing || !ar_reading)
1242 flush_archive ();
1243 if (cmd_mode == CMD_DELETE)
1244 {
1245 off_t pos;
1246
1247 pos = rmtlseek (archive, 0L, 1);
1248 #ifndef __MSDOS__
1249 (void) ftruncate (archive, pos);
1250 #else
1251 (void) rmtwrite (archive, "", 0);
1252 #endif
1253 }
1254 if (f_verify)
1255 verify_volume ();
1256
1257 if ((c = rmtclose (archive)) < 0)
1258 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1259
1260 #ifndef __MSDOS__
1261 if (childpid)
1262 {
1263 /*
1264 * Loop waiting for the right child to die, or for
1265 * no more kids.
1266 */
1267 while (((child = wait (&status)) != childpid) && child != -1)
1268 ;
1269
1270 if (child != -1)
1271 {
1272 if (WIFSIGNALED (status))
1273 {
1274 /* SIGPIPE is OK, everything else is a problem. */
1275 if (WTERMSIG (status) != SIGPIPE)
1276 msg ("child died with signal %d%s", WTERMSIG (status),
1277 WIFCOREDUMPED (status) ? " (core dumped)" : "");
1278 }
1279 else
1280 {
1281 /* Child voluntarily terminated -- but why? */
1282 if (WEXITSTATUS (status) == MAGIC_STAT)
1283 {
1284 exit (EX_SYSTEM); /* Child had trouble */
1285 }
1286 if (WEXITSTATUS (status) == (SIGPIPE + 128))
1287 {
1288 /*
1289 * /bin/sh returns this if its child
1290 * dies with SIGPIPE. 'Sok.
1291 */
1292 /* Do nothing. */
1293 }
1294 else if (WEXITSTATUS (status))
1295 msg ("child returned status %d",
1296 WEXITSTATUS (status));
1297 }
1298 }
1299 }
1300 #endif /* __MSDOS__ */
1301 }
1302
1303
1304 #ifdef DONTDEF
1305 /*
1306 * Message management.
1307 *
1308 * anno writes a message prefix on stream (eg stdout, stderr).
1309 *
1310 * The specified prefix is normally output followed by a colon and a space.
1311 * However, if other command line options are set, more output can come
1312 * out, such as the record # within the archive.
1313 *
1314 * If the specified prefix is NULL, no output is produced unless the
1315 * command line option(s) are set.
1316 *
1317 * If the third argument is 1, the "saved" record # is used; if 0, the
1318 * "current" record # is used.
1319 */
1320 void
1321 anno (stream, prefix, savedp)
1322 FILE *stream;
1323 char *prefix;
1324 int savedp;
1325 {
1326 # define MAXANNO 50
1327 char buffer[MAXANNO]; /* Holds annorecment */
1328 # define ANNOWIDTH 13
1329 int space;
1330 long offset;
1331 int save_e;
1332
1333 save_e = errno;
1334 /* Make sure previous output gets out in sequence */
1335 if (stream == stderr)
1336 fflush (stdout);
1337 if (f_sayblock)
1338 {
1339 if (prefix)
1340 {
1341 fputs (prefix, stream);
1342 putc (' ', stream);
1343 }
1344 offset = ar_record - ar_block;
1345 (void) sprintf (buffer, "rec %d: ",
1346 savedp ? saved_recno :
1347 baserec + offset);
1348 fputs (buffer, stream);
1349 space = ANNOWIDTH - strlen (buffer);
1350 if (space > 0)
1351 {
1352 fprintf (stream, "%*s", space, "");
1353 }
1354 }
1355 else if (prefix)
1356 {
1357 fputs (prefix, stream);
1358 fputs (": ", stream);
1359 }
1360 errno = save_e;
1361 }
1362
1363 #endif
1364
1365 /* Called to initialize the global volume number. */
1366 void
1367 init_volume_number ()
1368 {
1369 FILE *vf;
1370
1371 vf = fopen (f_volno_file, "r");
1372 if (!vf && errno != ENOENT)
1373 msg_perror ("%s", f_volno_file);
1374
1375 if (vf)
1376 {
1377 fscanf (vf, "%d", &global_volno);
1378 fclose (vf);
1379 }
1380 }
1381
1382 /* Called to write out the closing global volume number. */
1383 void
1384 closeout_volume_number ()
1385 {
1386 FILE *vf;
1387
1388 vf = fopen (f_volno_file, "w");
1389 if (!vf)
1390 msg_perror ("%s", f_volno_file);
1391 else
1392 {
1393 fprintf (vf, "%d\n", global_volno);
1394 fclose (vf);
1395 }
1396 }
1397
1398 /* We've hit the end of the old volume. Close it and open the next one */
1399 /* Values for type: 0: writing 1: reading 2: updating */
1400 int
1401 new_volume (type)
1402 int type;
1403 {
1404 int c;
1405 char inbuf[80];
1406 char *p;
1407 static FILE *read_file = 0;
1408 extern int now_verifying;
1409 extern char TTY_NAME[];
1410 static int looped = 0;
1411
1412 if (!read_file && !f_run_script_at_end)
1413 read_file = (archive == 0) ? fopen (TTY_NAME, "r") : stdin;
1414
1415 if (now_verifying)
1416 return -1;
1417 if (f_verify)
1418 verify_volume ();
1419 if ((c = rmtclose (archive)) < 0)
1420 msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
1421
1422 global_volno++;
1423 volno++;
1424 cur_ar_file++;
1425 if (cur_ar_file == n_ar_files)
1426 {
1427 cur_ar_file = 0;
1428 looped = 1;
1429 }
1430
1431 tryagain:
1432 if (looped)
1433 {
1434 /* We have to prompt from now on. */
1435 if (f_run_script_at_end)
1436 {
1437 closeout_volume_number ();
1438 system (info_script);
1439 }
1440 else
1441 for (;;)
1442 {
1443 fprintf (msg_file, "\007Prepare volume #%d for %s and hit return: ", global_volno, ar_files[cur_ar_file]);
1444 fflush (msg_file);
1445 if (fgets (inbuf, sizeof (inbuf), read_file) == 0)
1446 {
1447 fprintf (msg_file, "EOF? What does that mean?");
1448 if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
1449 msg ("Warning: Archive is INCOMPLETE!");
1450 exit (EX_BADARCH);
1451 }
1452 if (inbuf[0] == '\n' || inbuf[0] == 'y' || inbuf[0] == 'Y')
1453 break;
1454
1455 switch (inbuf[0])
1456 {
1457 case '?':
1458 {
1459 fprintf (msg_file, "\
1460 n [name] Give a new filename for the next (and subsequent) volume(s)\n\
1461 q Abort tar\n\
1462 ! Spawn a subshell\n\
1463 ? Print this list\n");
1464 }
1465 break;
1466
1467 case 'q': /* Quit */
1468 fprintf (msg_file, "No new volume; exiting.\n");
1469 if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
1470 msg ("Warning: Archive is INCOMPLETE!");
1471 exit (EX_BADARCH);
1472
1473 case 'n': /* Get new file name */
1474 {
1475 char *q, *r;
1476 static char *old_name;
1477
1478 for (q = &inbuf[1]; *q == ' ' || *q == '\t'; q++)
1479 ;
1480 for (r = q; *r; r++)
1481 if (*r == '\n')
1482 *r = '\0';
1483 old_name = p = (char *) malloc ((unsigned) (strlen (q) + 2));
1484 if (p == 0)
1485 {
1486 msg ("Can't allocate memory for name");
1487 exit (EX_SYSTEM);
1488 }
1489 (void) strcpy (p, q);
1490 ar_files[cur_ar_file] = p;
1491 }
1492 break;
1493
1494 case '!':
1495 #ifdef __MSDOS__
1496 spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
1497 #else
1498 /* JF this needs work! */
1499 switch (fork ())
1500 {
1501 case -1:
1502 msg_perror ("can't fork!");
1503 break;
1504 case 0:
1505 p = getenv ("SHELL");
1506 if (p == 0)
1507 p = "/bin/sh";
1508 execlp (p, "-sh", "-i", 0);
1509 msg_perror ("can't exec a shell %s", p);
1510 _exit (55);
1511 default:
1512 wait (0);
1513 break;
1514 }
1515 #endif
1516 break;
1517 }
1518 }
1519 }
1520
1521
1522 if (type == 2 || f_verify)
1523 archive = rmtopen (ar_files[cur_ar_file], O_RDWR | O_CREAT, 0666);
1524 else if (type == 1)
1525 archive = rmtopen (ar_files[cur_ar_file], O_RDONLY, 0666);
1526 else if (type == 0)
1527 archive = rmtcreat (ar_files[cur_ar_file], 0666);
1528 else
1529 archive = -1;
1530
1531 if (archive < 0)
1532 {
1533 msg_perror ("can't open %s", ar_files[cur_ar_file]);
1534 goto tryagain;
1535 }
1536 #ifdef __MSDOS__
1537 setmode (archive, O_BINARY);
1538 #endif
1539 return 0;
1540 }
1541
1542 /* this is a useless function that takes a buffer returned by wantbytes
1543 and does nothing with it. If the function called by wantbytes returns
1544 an error indicator (non-zero), this function is called for the rest of
1545 the file.
1546 */
1547 int
1548 no_op (size, data)
1549 int size;
1550 char *data;
1551 {
1552 return 0;
1553 }
1554
1555 /* Some other routine wants SIZE bytes in the archive. For each chunk of
1556 the archive, call FUNC with the size of the chunk, and the address of
1557 the chunk it can work with.
1558 */
1559 int
1560 wantbytes (size, func)
1561 long size;
1562 int (*func) ();
1563 {
1564 char *data;
1565 long data_size;
1566
1567 while (size)
1568 {
1569 data = findrec ()->charptr;
1570 if (data == NULL)
1571 { /* Check it... */
1572 msg ("Unexpected EOF on archive file");
1573 return -1;
1574 }
1575 data_size = endofrecs ()->charptr - data;
1576 if (data_size > size)
1577 data_size = size;
1578 if ((*func) (data_size, data))
1579 func = no_op;
1580 userec ((union record *) (data + data_size - 1));
1581 size -= data_size;
1582 }
1583 return 0;
1584 }
This page took 0.099978 seconds and 5 git commands to generate.