]>
Dogcows Code - chaz/tar/blob - src/buffer.c
1 /* Buffer management for tar.
2 Copyright (C) 1988, 1992 Free Software Foundation
4 This file is part of GNU Tar.
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)
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.
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. */
21 * Buffer management for tar.
23 * Written by John Gilmore, ihnp4!hoptoad!gnu, on 25 August 1985.
31 #include <sys/types.h> /* For non-Berkeley systems */
36 #ifdef HAVE_SYS_MTIO_H
37 #include <sys/ioctl.h>
54 #include <sys/inode.h>
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
;
66 #define STDIN 0 /* Standard input file descriptor */
67 #define STDOUT 1 /* Standard output file descriptor */
69 #define PREAD 0 /* Read file descriptor from pipe() */
70 #define PWRITE 1 /* Write file descriptor from pipe() */
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! */
84 int backspace_output ();
85 extern void finish_header ();
86 void flush_archive ();
89 void verify_volume ();
90 extern void to_oct ();
93 /* Obnoxious test to see if dimwit is trying to dump the archive */
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
106 static union record
**save_rec
;
107 union record record_save_area
;
108 static long saved_recno
;
111 * PID of child program, if f_compress or remote archive access.
113 static int childpid
= 0;
116 * Record number of the start of this block of records
121 * Error recovery stuff
123 static int r_error_count
;
126 * Have we hit EOF yet?
130 /* Checkpointing counter */
131 static int checkpoint
;
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 */
138 static int volno
= 1; /* JF which volume of a multi-volume tape
140 static int global_volno
= 1; /* Volume number to print in external messages. */
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 */
148 int write_archive_to_stdout
;
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
;
155 /* Reset the EOF flag (if set), and re-set ar_record, etc */
163 ar_record
= ar_block
;
164 ar_last
= ar_block
+ blocking
;
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".
177 if (ar_record
== ar_last
)
180 return (union record
*) NULL
; /* EOF */
182 if (ar_record
== ar_last
)
185 return (union record
*) NULL
; /* EOF */
193 * Indicate that we have used all records up thru the argument.
194 * (should the arg have an off-by-1? XXX FIXME)
200 while (rec
>= ar_record
)
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
208 if (ar_record
> ar_last
)
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.
226 * Duplicate a file descriptor into a certain slot.
227 * Equivalent to BSD "dup2" with error reporting.
230 dupto (from
, to
, msg
)
239 if (err
< 0 && errno
!= EBADF
)
241 msg_perror ("Cannot close descriptor %d", to
);
247 msg_perror ("cannot dup %s", msg
);
258 fprintf (stderr
, "MS-DOS %s can't use compressed or remote archives\n", tar
);
280 msg_perror ("cannot fork");
285 /* We're the parent. Clean up and be happy */
286 /* This, at least, is easy */
291 archive
= pipe
[READ
];
292 ck_close (pipe
[WRITE
]);
296 archive
= pipe
[WRITE
];
297 ck_close (pipe
[READ
]);
305 dupto (pipe
[WRITE
], STDOUT
, "(child) pipe to stdout");
306 ck_close (pipe
[READ
]);
310 dupto (pipe
[READ
], STDIN
, "(child) pipe to stdin");
311 ck_close (pipe
[WRITE
]);
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 */
319 if (!(ar_files
[0][0] == '-' && ar_files
[0][1] == '\0') && isfile (ar_files
[0]))
321 if (!(ar_files
[0][0] == '-' && ar_files
[0][1] == '\0') && !_remdev (ar_files
[0]) && isfile (ar_files
[0]))
324 /* We don't need a child tar. Open the archive */
327 archive
= open (ar_files
[0], O_RDONLY
| O_BINARY
, 0666);
330 msg_perror ("can't open archive %s", ar_files
[0]);
333 dupto (archive
, STDIN
, "archive to stdin");
334 /* close(archive); */
338 archive
= creat (ar_files
[0], 0666);
341 msg_perror ("can't open archive %s", ar_files
[0]);
344 dupto (archive
, STDOUT
, "archive to stdout");
345 /* close(archive); */
350 /* We need a child tar */
353 kidchildpid
= fork ();
356 msg_perror ("child can't fork");
362 /* About to exec compress: set up the files */
365 dupto (kidpipe
[READ
], STDIN
, "((child)) pipe to stdin");
366 ck_close (kidpipe
[WRITE
]);
367 /* dup2(pipe[WRITE],STDOUT); */
371 /* dup2(pipe[READ],STDIN); */
372 dupto (kidpipe
[WRITE
], STDOUT
, "((child)) pipe to stdout");
373 ck_close (kidpipe
[READ
]);
375 /* ck_close(pipe[READ]); */
376 /* ck_close(pipe[WRITE]); */
377 /* ck_close(kidpipe[READ]);
378 ck_close(kidpipe[WRITE]); */
382 /* Grandchild. Do the right thing, namely sit here and
383 read/write the archive, and feed stuff back to compress */
387 dupto (kidpipe
[WRITE
], STDOUT
, "[child] pipe to stdout");
388 ck_close (kidpipe
[READ
]);
392 dupto (kidpipe
[READ
], STDIN
, "[child] pipe to stdin");
393 ck_close (kidpipe
[WRITE
]);
396 if (ar_files
[0][0] == '-' && ar_files
[0][1] == '\0')
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);
408 archive
= rmtcreat (ar_files
[0], 0666);
412 msg_perror ("can't open archive %s", ar_files
[0]);
425 err
= rmtread (archive
, ar_block
->charptr
, (int) (blocksize
));
433 ptr
= ar_block
->charptr
;
437 count
= (max
< RECORDSIZE
) ? max
: RECORDSIZE
;
438 err
= write (STDOUT
, ptr
, count
);
443 msg_perror ("can't write to compress");
447 msg ("write to compress short %d bytes", count
- err
);
448 count
= (err
< 0) ? 0 : err
;
463 ptr
= ar_block
->charptr
;
466 err
= read (STDIN
, ptr
, (n
< RECORDSIZE
) ? n
: RECORDSIZE
);
478 bzero (ar_block
->charptr
+ blocksize
- n
, n
);
479 err
= rmtwrite (archive
, ar_block
->charptr
, blocksize
);
480 if (err
!= (blocksize
))
488 msg_perror ("can't read from compress");
491 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
492 if (err
!= blocksize
)
497 /* close_archive(); */
501 /* So we should exec compress (-d) */
503 execlp ("compress", "compress", "-d", (char *) 0);
505 execlp ("compress", "compress", (char *) 0);
506 msg_perror ("can't exec compress");
511 /* return non-zero if p is the name of a directory */
518 if (stat (p
, &stbuf
) < 0)
520 if (S_ISREG (stbuf
.st_mode
))
528 * Open an archive file. The argument specifies whether we are
529 * reading or writing.
531 /* JF if the arg is 2, open for reading and writing. */
533 open_archive (reading
)
536 msg_file
= f_exstdout
? stderr
: stdout
;
540 msg ("invalid value for blocksize");
546 msg ("No archive name given, what should I do?");
553 ar_block
= (union record
*) valloc ((unsigned) (blocksize
+ (2 * RECORDSIZE
)));
558 ar_block
= (union record
*) valloc ((unsigned) blocksize
);
561 msg ("could not allocate memory for blocking factor %d",
566 ar_record
= ar_block
;
567 ar_last
= ar_block
+ blocking
;
568 ar_reading
= reading
;
570 if (f_multivol
&& f_verify
)
572 msg ("cannot verify multi-volume archives");
578 if (reading
== 2 || f_verify
)
580 msg ("cannot update or verify compressed archives");
585 msg ("cannot use multi-volume compressed archives");
589 if (!reading
&& ar_files
[0][0] == '-' && ar_files
[0][1] == '\0')
591 /* child_open(rem_host, rem_file); */
593 else if (ar_files
[0][0] == '-' && ar_files
[0][1] == '\0')
595 f_reblock
++; /* Could be a pipe, be safe */
598 msg ("can't verify stdin/stdout archive");
605 write_archive_to_stdout
++;
615 else if (reading
== 2 || f_verify
)
617 archive
= rmtopen (ar_files
[0], O_RDWR
| O_CREAT
| O_BINARY
, 0666);
621 archive
= rmtopen (ar_files
[0], O_RDONLY
| O_BINARY
, 0666);
625 archive
= rmtcreat (ar_files
[0], 0666);
629 msg_perror ("can't open %s", ar_files
[0]);
633 if (!_isrmt (archive
))
635 struct stat tmp_stat
;
637 fstat (archive
, &tmp_stat
);
638 if (S_ISREG (tmp_stat
.st_mode
))
640 ar_dev
= tmp_stat
.st_dev
;
641 ar_ino
= tmp_stat
.st_ino
;
647 setmode (archive
, O_BINARY
);
652 ar_last
= ar_block
; /* Set up for 1st block = # 0 */
653 (void) findrec (); /* Read it in, check for EOF */
663 ptr
= malloc (strlen (f_volhdr
) + 20);
664 sprintf (ptr
, "%s Volume %d", f_volhdr
, 1);
672 msg ("Archive not labelled to match %s", f_volhdr
);
675 if (re_match (label_pattern
, head
->header
.arch_name
,
676 strlen (head
->header
.arch_name
), 0, 0) < 0)
678 msg ("Volume mismatch! %s!=%s", f_volhdr
,
679 head
->header
.arch_name
);
683 if (strcmp (ptr
, head
->header
.name
))
685 msg ("Volume mismatch! %s!=%s", ptr
, head
->header
.name
);
695 bzero ((void *) ar_block
, RECORDSIZE
);
697 sprintf (ar_block
->header
.arch_name
, "%s Volume 1", f_volhdr
);
699 strcpy (ar_block
->header
.arch_name
, f_volhdr
);
700 ar_block
->header
.linkflag
= LF_VOLHDR
;
701 to_oct (time (0), 1 + 12, ar_block
->header
.mtime
);
702 finish_header (ar_block
);
709 * Remember a union record * as pointing to something that we
710 * need to keep when reading onward in the file. Only one such
711 * thing can be remembered at once, and it only works when reading
714 * We calculate "offset" then add it because some compilers end up
715 * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
716 * subtracting ar_block from that, shifting it back, losing the top 9 bits.
720 union record
**pointer
;
725 offset
= ar_record
- ar_block
;
726 saved_recno
= baserec
+ offset
;
730 * Perform a write to flush the buffer.
733 /*send_buffer_to_file();
735 deal_with_new_volume_stuff();
736 send_buffer_to_file();
745 static long bytes_written
= 0;
747 if (f_checkpoint
&& !(++checkpoint
% 10))
748 msg ("Write checkpoint %d\n", checkpoint
);
749 if (tape_length
&& bytes_written
>= tape_length
* 1024)
755 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
756 if (err
!= blocksize
&& !f_multivol
)
759 tot_written
+= blocksize
;
762 bytes_written
+= err
;
763 if (err
== blocksize
)
769 real_s_name
[0] = '\0';
775 if (save_name
[1] == ':')
778 while (*save_name
== '/')
781 strcpy (real_s_name
, save_name
);
782 real_s_totsize
= save_totsize
;
783 real_s_sizeleft
= save_sizeleft
;
788 /* We're multivol Panic if we didn't get the right kind of response */
789 /* ENXIO is for the UNIX PC */
790 if (err
< 0 && errno
!= ENOSPC
&& errno
!= EIO
&& errno
!= ENXIO
)
793 /* If error indicates a short write, we just move to the next tape. */
795 if (new_volume (0) < 0)
798 if (f_volhdr
&& real_s_name
[0])
803 else if (f_volhdr
|| real_s_name
[0])
812 bzero ((void *) ar_block
, RECORDSIZE
);
813 sprintf (ar_block
->header
.arch_name
, "%s Volume %d", f_volhdr
, volno
);
814 to_oct (time (0), 1 + 12, ar_block
->header
.mtime
);
815 ar_block
->header
.linkflag
= LF_VOLHDR
;
816 finish_header (ar_block
);
824 bzero ((void *) ar_block
, RECORDSIZE
);
825 strcpy (ar_block
->header
.arch_name
, real_s_name
);
826 ar_block
->header
.linkflag
= LF_MULTIVOL
;
827 to_oct ((long) real_s_sizeleft
, 1 + 12,
828 ar_block
->header
.size
);
829 to_oct ((long) real_s_totsize
- real_s_sizeleft
,
830 1 + 12, ar_block
->header
.offset
);
833 finish_header (ar_block
);
839 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
840 if (err
!= blocksize
)
843 tot_written
+= blocksize
;
846 bytes_written
= blocksize
;
849 ar_block
+= copy_back
;
850 bcopy ((void *) (ar_block
+ blocking
- copy_back
),
852 copy_back
* RECORDSIZE
);
853 ar_record
+= copy_back
;
855 if (real_s_sizeleft
>= copy_back
* RECORDSIZE
)
856 real_s_sizeleft
-= copy_back
* RECORDSIZE
;
857 else if ((real_s_sizeleft
+ RECORDSIZE
- 1) / RECORDSIZE
<= copy_back
)
858 real_s_name
[0] = '\0';
862 if (save_name
[1] == ':')
865 while (*save_name
== '/')
868 strcpy (real_s_name
, save_name
);
869 real_s_sizeleft
= save_sizeleft
;
870 real_s_totsize
= save_totsize
;
876 /* Handle write errors on the archive. Write errors are always fatal */
877 /* Hitting the end of a volume does not cause a write error unless the write
878 * was the first block of the volume */
886 msg_perror ("can't write to %s", ar_files
[cur_ar_file
]);
891 msg ("only wrote %u of %u bytes to %s", err
, blocksize
, ar_files
[cur_ar_file
]);
897 * Handle read errors on the archive.
899 * If the read should be retried, readerror() returns to the caller.
904 # define READ_ERROR_MAX 10
906 read_error_flag
++; /* Tell callers */
908 msg_perror ("read error on %s", ar_files
[cur_ar_file
]);
912 /* First block of tape. Probably stupidity error */
917 * Read error in mid archive. We retry up to READ_ERROR_MAX times
918 * and then give up on reading the archive. We set read_error_flag
919 * for our callers, so they can cope if they want.
921 if (r_error_count
++ > READ_ERROR_MAX
)
923 msg ("Too many errors, quitting.");
931 * Perform a read to flush the buffer.
936 int err
; /* Result from system call */
937 int left
; /* Bytes left */
938 char *more
; /* Pointer to next byte to read */
940 if (f_checkpoint
&& !(++checkpoint
% 10))
941 msg ("Read checkpoint %d\n", checkpoint
);
944 * Clear the count of errors. This only applies to a single
945 * call to fl_read. We leave read_error_flag alone; it is
946 * only turned off by higher level software.
948 r_error_count
= 0; /* Clear error count */
951 * If we are about to wipe out a record that
952 * somebody needs to keep, copy it out to a holding
953 * area and adjust somebody's pointer to it.
956 *save_rec
>= ar_record
&&
959 record_save_area
= **save_rec
;
960 *save_rec
= &record_save_area
;
962 if (write_archive_to_stdout
&& baserec
!= 0)
964 err
= rmtwrite (1, ar_block
->charptr
, blocksize
);
965 if (err
!= blocksize
)
972 if (save_name
!= real_s_name
)
975 if (save_name
[1] == ':')
978 while (*save_name
== '/')
981 strcpy (real_s_name
, save_name
);
982 save_name
= real_s_name
;
984 real_s_totsize
= save_totsize
;
985 real_s_sizeleft
= save_sizeleft
;
990 real_s_name
[0] = '\0';
997 err
= rmtread (archive
, ar_block
->charptr
, (int) blocksize
);
998 if (err
== blocksize
)
1001 if ((err
== 0 || (err
< 0 && errno
== ENOSPC
) || (err
> 0 && !f_reblock
)) && f_multivol
)
1006 if (new_volume ((cmd_mode
== CMD_APPEND
|| cmd_mode
== CMD_CAT
|| cmd_mode
== CMD_UPDATE
) ? 2 : 1) < 0)
1009 err
= rmtread (archive
, ar_block
->charptr
, (int) blocksize
);
1015 if (err
!= blocksize
)
1020 if (head
->header
.linkflag
== LF_VOLHDR
)
1027 ptr
= (char *) malloc (strlen (f_volhdr
) + 20);
1028 sprintf (ptr
, "%s Volume %d", f_volhdr
, volno
);
1030 if (re_match (label_pattern
, head
->header
.arch_name
,
1031 strlen (head
->header
.arch_name
),
1034 msg ("Volume mismatch! %s!=%s", f_volhdr
,
1035 head
->header
.arch_name
);
1042 if (strcmp (ptr
, head
->header
.name
))
1044 msg ("Volume mismatch! %s!=%s", ptr
, head
->header
.name
);
1054 fprintf (msg_file
, "Reading %s\n", head
->header
.arch_name
);
1059 msg ("Warning: No volume header!");
1066 if (head
->header
.linkflag
!= LF_MULTIVOL
|| strcmp (head
->header
.arch_name
, real_s_name
))
1068 msg ("%s is not continued on this volume!", real_s_name
);
1073 if (real_s_totsize
!= from_oct (1 + 12, head
->header
.size
) + from_oct (1 + 12, head
->header
.offset
))
1075 msg ("%s is the wrong size (%ld!=%ld+%ld)",
1076 head
->header
.arch_name
, save_totsize
,
1077 from_oct (1 + 12, head
->header
.size
),
1078 from_oct (1 + 12, head
->header
.offset
));
1083 if (real_s_totsize
- real_s_sizeleft
!= from_oct (1 + 12, head
->header
.offset
))
1085 msg ("This volume is out of sequence");
1098 goto error_loop
; /* Try again */
1102 more
= ar_block
->charptr
+ err
;
1103 left
= blocksize
- err
;
1106 if (0 == (((unsigned) left
) % RECORDSIZE
))
1108 /* FIXME, for size=0, multi vol support */
1109 /* On the first block, warn about the problem */
1110 if (!f_reblock
&& baserec
== 0 && f_verbose
&& err
> 0)
1112 /* msg("Blocksize = %d record%s",
1113 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
1114 msg ("Blocksize = %d records", err
/ RECORDSIZE
);
1116 ar_last
= ar_block
+ ((unsigned) (blocksize
- left
)) / RECORDSIZE
;
1122 * User warned us about this. Fix up.
1127 err
= rmtread (archive
, more
, (int) left
);
1131 goto error2loop
; /* Try again */
1135 msg ("archive %s EOF not on block boundary", ar_files
[cur_ar_file
]);
1145 msg ("only read %d bytes from archive %s", err
, ar_files
[cur_ar_file
]);
1152 * Flush the current buffer to/from the archive.
1159 baserec
+= ar_last
- ar_block
;/* Keep track of block #s */
1160 ar_record
= ar_block
; /* Restore pointer to start */
1161 ar_last
= ar_block
+ blocking
;/* Restore pointer to end */
1165 if (time_to_start_writing
)
1167 time_to_start_writing
= 0;
1170 if (file_to_switch_to
>= 0)
1172 if ((c
= rmtclose (archive
)) < 0)
1173 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1175 archive
= file_to_switch_to
;
1178 (void) backspace_output ();
1190 /* Backspace the archive descriptor by one blocks worth.
1191 If its a tape, MTIOCTOP will work. If its something else,
1192 we try to seek on it. If we can't seek, we lose! */
1198 extern char *output_start
;
1205 if ((rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
1207 if (errno
== EIO
&& (rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
1211 cur
= rmtlseek (archive
, 0L, 1);
1213 /* Seek back to the beginning of this block and
1214 start writing there. */
1216 if (rmtlseek (archive
, cur
, 0) != cur
)
1218 /* Lseek failed. Try a different method */
1219 msg ("Couldn't backspace archive file. It may be unreadable without -i.");
1220 /* Replace the first part of the block with nulls */
1221 if (ar_block
->charptr
!= output_start
)
1222 bzero (ar_block
->charptr
, output_start
- ar_block
->charptr
);
1230 * Close the archive file.
1239 if (time_to_start_writing
|| !ar_reading
)
1241 if (cmd_mode
== CMD_DELETE
)
1245 pos
= rmtlseek (archive
, 0L, 1);
1247 (void) ftruncate (archive
, pos
);
1249 (void) rmtwrite (archive
, "", 0);
1255 if ((c
= rmtclose (archive
)) < 0)
1256 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1262 * Loop waiting for the right child to die, or for
1265 while (((child
= wait (&status
)) != childpid
) && child
!= -1)
1270 if (WIFSIGNALED (status
))
1272 /* SIGPIPE is OK, everything else is a problem. */
1273 if (WTERMSIG (status
) != SIGPIPE
)
1274 msg ("child died with signal %d%s", WTERMSIG (status
),
1275 WIFCOREDUMPED (status
) ? " (core dumped)" : "");
1279 /* Child voluntarily terminated -- but why? */
1280 if (WEXITSTATUS (status
) == MAGIC_STAT
)
1282 exit (EX_SYSTEM
); /* Child had trouble */
1284 if (WEXITSTATUS (status
) == (SIGPIPE
+ 128))
1287 * /bin/sh returns this if its child
1288 * dies with SIGPIPE. 'Sok.
1292 else if (WEXITSTATUS (status
))
1293 msg ("child returned status %d",
1294 WEXITSTATUS (status
));
1298 #endif /* __MSDOS__ */
1304 * Message management.
1306 * anno writes a message prefix on stream (eg stdout, stderr).
1308 * The specified prefix is normally output followed by a colon and a space.
1309 * However, if other command line options are set, more output can come
1310 * out, such as the record # within the archive.
1312 * If the specified prefix is NULL, no output is produced unless the
1313 * command line option(s) are set.
1315 * If the third argument is 1, the "saved" record # is used; if 0, the
1316 * "current" record # is used.
1319 anno (stream
, prefix
, savedp
)
1325 char buffer
[MAXANNO
]; /* Holds annorecment */
1326 # define ANNOWIDTH 13
1332 /* Make sure previous output gets out in sequence */
1333 if (stream
== stderr
)
1339 fputs (prefix
, stream
);
1342 offset
= ar_record
- ar_block
;
1343 (void) sprintf (buffer
, "rec %d: ",
1344 savedp
? saved_recno
:
1346 fputs (buffer
, stream
);
1347 space
= ANNOWIDTH
- strlen (buffer
);
1350 fprintf (stream
, "%*s", space
, "");
1355 fputs (prefix
, stream
);
1356 fputs (": ", stream
);
1363 /* Called to initialize the global volume number. */
1365 init_volume_number ()
1369 vf
= fopen (f_volno_file
, "r");
1370 if (!vf
&& errno
!= ENOENT
)
1371 msg_perror ("%s", f_volno_file
);
1375 fscanf (vf
, "%d", &global_volno
);
1380 /* Called to write out the closing global volume number. */
1382 closeout_volume_number ()
1386 vf
= fopen (f_volno_file
, "w");
1388 msg_perror ("%s", f_volno_file
);
1391 fprintf (vf
, "%d\n", global_volno
);
1396 /* We've hit the end of the old volume. Close it and open the next one */
1397 /* Values for type: 0: writing 1: reading 2: updating */
1405 static FILE *read_file
= 0;
1406 extern int now_verifying
;
1407 extern char TTY_NAME
[];
1408 static int looped
= 0;
1410 if (!read_file
&& !f_run_script_at_end
)
1411 read_file
= (archive
== 0) ? fopen (TTY_NAME
, "r") : stdin
;
1417 if ((c
= rmtclose (archive
)) < 0)
1418 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1423 if (cur_ar_file
== n_ar_files
)
1432 /* We have to prompt from now on. */
1433 if (f_run_script_at_end
)
1434 system (info_script
);
1438 fprintf (msg_file
, "\007Prepare volume #%d for %s and hit return: ", global_volno
, ar_files
[cur_ar_file
]);
1440 if (fgets (inbuf
, sizeof (inbuf
), read_file
) == 0)
1442 fprintf (msg_file
, "EOF? What does that mean?");
1443 if (cmd_mode
!= CMD_EXTRACT
&& cmd_mode
!= CMD_LIST
&& cmd_mode
!= CMD_DIFF
)
1444 msg ("Warning: Archive is INCOMPLETE!");
1447 if (inbuf
[0] == '\n' || inbuf
[0] == 'y' || inbuf
[0] == 'Y')
1454 fprintf (msg_file
, "\
1455 n [name] Give a new filename for the next (and subsequent) volume(s)\n\
1457 ! Spawn a subshell\n\
1458 ? Print this list\n");
1462 case 'q': /* Quit */
1463 fprintf (msg_file
, "No new volume; exiting.\n");
1464 if (cmd_mode
!= CMD_EXTRACT
&& cmd_mode
!= CMD_LIST
&& cmd_mode
!= CMD_DIFF
)
1465 msg ("Warning: Archive is INCOMPLETE!");
1468 case 'n': /* Get new file name */
1471 static char *old_name
;
1473 for (q
= &inbuf
[1]; *q
== ' ' || *q
== '\t'; q
++)
1475 for (r
= q
; *r
; r
++)
1478 old_name
= p
= (char *) malloc ((unsigned) (strlen (q
) + 2));
1481 msg ("Can't allocate memory for name");
1484 (void) strcpy (p
, q
);
1485 ar_files
[cur_ar_file
] = p
;
1491 spawnl (P_WAIT
, getenv ("COMSPEC"), "-", 0);
1493 /* JF this needs work! */
1497 msg_perror ("can't fork!");
1500 p
= getenv ("SHELL");
1503 execlp (p
, "-sh", "-i", 0);
1504 msg_perror ("can't exec a shell %s", p
);
1517 if (type
== 2 || f_verify
)
1518 archive
= rmtopen (ar_files
[cur_ar_file
], O_RDWR
| O_CREAT
, 0666);
1520 archive
= rmtopen (ar_files
[cur_ar_file
], O_RDONLY
, 0666);
1522 archive
= rmtcreat (ar_files
[cur_ar_file
], 0666);
1528 msg_perror ("can't open %s", ar_files
[cur_ar_file
]);
1532 setmode (archive
, O_BINARY
);
1537 /* this is a useless function that takes a buffer returned by wantbytes
1538 and does nothing with it. If the function called by wantbytes returns
1539 an error indicator (non-zero), this function is called for the rest of
1550 /* Some other routine wants SIZE bytes in the archive. For each chunk of
1551 the archive, call FUNC with the size of the chunk, and the address of
1552 the chunk it can work with.
1555 wantbytes (size
, func
)
1564 data
= findrec ()->charptr
;
1567 msg ("Unexpected EOF on archive file");
1570 data_size
= endofrecs ()->charptr
- data
;
1571 if (data_size
> size
)
1573 if ((*func
) (data_size
, data
))
1575 userec ((union record
*) (data
+ data_size
- 1));
This page took 0.108794 seconds and 5 git commands to generate.