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