*** empty log message ***
[debian/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 }