]>
Dogcows Code - chaz/tar/blob - src/buffer.c
1 /* Buffer management for tar.
2 Copyright (C) 1988, 1992, 1993 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 current_file_name
= ar_block
->header
.arch_name
;
701 ar_block
->header
.linkflag
= LF_VOLHDR
;
702 to_oct (time (0), 1 + 12, ar_block
->header
.mtime
);
703 finish_header (ar_block
);
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
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.
721 union record
**pointer
;
726 offset
= ar_record
- ar_block
;
727 saved_recno
= baserec
+ offset
;
731 * Perform a write to flush the buffer.
734 /*send_buffer_to_file();
736 deal_with_new_volume_stuff();
737 send_buffer_to_file();
746 static long bytes_written
= 0;
748 if (f_checkpoint
&& !(++checkpoint
% 10))
749 msg ("Write checkpoint %d\n", checkpoint
);
750 if (tape_length
&& bytes_written
>= tape_length
* 1024)
756 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
757 if (err
!= blocksize
&& !f_multivol
)
760 tot_written
+= blocksize
;
763 bytes_written
+= err
;
764 if (err
== blocksize
)
770 real_s_name
[0] = '\0';
776 if (save_name
[1] == ':')
779 while (*save_name
== '/')
782 strcpy (real_s_name
, save_name
);
783 real_s_totsize
= save_totsize
;
784 real_s_sizeleft
= save_sizeleft
;
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
)
794 /* If error indicates a short write, we just move to the next tape. */
796 if (new_volume (0) < 0)
799 if (f_volhdr
&& real_s_name
[0])
804 else if (f_volhdr
|| real_s_name
[0])
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
);
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
);
834 finish_header (ar_block
);
840 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
841 if (err
!= blocksize
)
844 tot_written
+= blocksize
;
847 bytes_written
= blocksize
;
850 ar_block
+= copy_back
;
851 bcopy ((void *) (ar_block
+ blocking
- copy_back
),
853 copy_back
* RECORDSIZE
);
854 ar_record
+= copy_back
;
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';
863 if (save_name
[1] == ':')
866 while (*save_name
== '/')
869 strcpy (real_s_name
, save_name
);
870 real_s_sizeleft
= save_sizeleft
;
871 real_s_totsize
= save_totsize
;
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 */
887 msg_perror ("can't write to %s", ar_files
[cur_ar_file
]);
892 msg ("only wrote %u of %u bytes to %s", err
, blocksize
, ar_files
[cur_ar_file
]);
898 * Handle read errors on the archive.
900 * If the read should be retried, readerror() returns to the caller.
905 # define READ_ERROR_MAX 10
907 read_error_flag
++; /* Tell callers */
909 msg_perror ("read error on %s", ar_files
[cur_ar_file
]);
913 /* First block of tape. Probably stupidity error */
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.
922 if (r_error_count
++ > READ_ERROR_MAX
)
924 msg ("Too many errors, quitting.");
932 * Perform a read to flush the buffer.
937 int err
; /* Result from system call */
938 int left
; /* Bytes left */
939 char *more
; /* Pointer to next byte to read */
941 if (f_checkpoint
&& !(++checkpoint
% 10))
942 msg ("Read checkpoint %d\n", checkpoint
);
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.
949 r_error_count
= 0; /* Clear error count */
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.
957 *save_rec
>= ar_record
&&
960 record_save_area
= **save_rec
;
961 *save_rec
= &record_save_area
;
963 if (write_archive_to_stdout
&& baserec
!= 0)
965 err
= rmtwrite (1, ar_block
->charptr
, blocksize
);
966 if (err
!= blocksize
)
973 if (save_name
!= real_s_name
)
976 if (save_name
[1] == ':')
979 while (*save_name
== '/')
982 strcpy (real_s_name
, save_name
);
983 save_name
= real_s_name
;
985 real_s_totsize
= save_totsize
;
986 real_s_sizeleft
= save_sizeleft
;
991 real_s_name
[0] = '\0';
998 err
= rmtread (archive
, ar_block
->charptr
, (int) blocksize
);
999 if (err
== blocksize
)
1002 if ((err
== 0 || (err
< 0 && errno
== ENOSPC
) || (err
> 0 && !f_reblock
)) && f_multivol
)
1007 if (new_volume ((cmd_mode
== CMD_APPEND
|| cmd_mode
== CMD_CAT
|| cmd_mode
== CMD_UPDATE
) ? 2 : 1) < 0)
1010 err
= rmtread (archive
, ar_block
->charptr
, (int) blocksize
);
1016 if (err
!= blocksize
)
1021 if (head
->header
.linkflag
== LF_VOLHDR
)
1028 ptr
= (char *) malloc (strlen (f_volhdr
) + 20);
1029 sprintf (ptr
, "%s Volume %d", f_volhdr
, volno
);
1031 if (re_match (label_pattern
, head
->header
.arch_name
,
1032 strlen (head
->header
.arch_name
),
1035 msg ("Volume mismatch! %s!=%s", f_volhdr
,
1036 head
->header
.arch_name
);
1043 if (strcmp (ptr
, head
->header
.name
))
1045 msg ("Volume mismatch! %s!=%s", ptr
, head
->header
.name
);
1055 fprintf (msg_file
, "Reading %s\n", head
->header
.arch_name
);
1060 msg ("Warning: No volume header!");
1067 if (head
->header
.linkflag
!= LF_MULTIVOL
|| strcmp (head
->header
.arch_name
, real_s_name
))
1069 msg ("%s is not continued on this volume!", real_s_name
);
1074 if (real_s_totsize
!= from_oct (1 + 12, head
->header
.size
) + from_oct (1 + 12, head
->header
.offset
))
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
));
1084 if (real_s_totsize
- real_s_sizeleft
!= from_oct (1 + 12, head
->header
.offset
))
1086 msg ("This volume is out of sequence");
1099 goto error_loop
; /* Try again */
1103 more
= ar_block
->charptr
+ err
;
1104 left
= blocksize
- err
;
1107 if (0 == (((unsigned) left
) % RECORDSIZE
))
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)
1113 /* msg("Blocksize = %d record%s",
1114 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
1115 msg ("Blocksize = %d records", err
/ RECORDSIZE
);
1117 ar_last
= ar_block
+ ((unsigned) (blocksize
- left
)) / RECORDSIZE
;
1123 * User warned us about this. Fix up.
1128 err
= rmtread (archive
, more
, (int) left
);
1132 goto error2loop
; /* Try again */
1136 msg ("archive %s EOF not on block boundary", ar_files
[cur_ar_file
]);
1146 msg ("only read %d bytes from archive %s", err
, ar_files
[cur_ar_file
]);
1153 * Flush the current buffer to/from the archive.
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 */
1166 if (time_to_start_writing
)
1168 time_to_start_writing
= 0;
1171 if (file_to_switch_to
>= 0)
1173 if ((c
= rmtclose (archive
)) < 0)
1174 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1176 archive
= file_to_switch_to
;
1179 (void) backspace_output ();
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! */
1199 extern char *output_start
;
1206 if ((rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
1208 if (errno
== EIO
&& (rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
1212 cur
= rmtlseek (archive
, 0L, 1);
1214 /* Seek back to the beginning of this block and
1215 start writing there. */
1217 if (rmtlseek (archive
, cur
, 0) != cur
)
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
);
1231 * Close the archive file.
1240 if (time_to_start_writing
|| !ar_reading
)
1242 if (cmd_mode
== CMD_DELETE
)
1246 pos
= rmtlseek (archive
, 0L, 1);
1248 (void) ftruncate (archive
, pos
);
1250 (void) rmtwrite (archive
, "", 0);
1256 if ((c
= rmtclose (archive
)) < 0)
1257 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1263 * Loop waiting for the right child to die, or for
1266 while (((child
= wait (&status
)) != childpid
) && child
!= -1)
1271 if (WIFSIGNALED (status
))
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)" : "");
1280 /* Child voluntarily terminated -- but why? */
1281 if (WEXITSTATUS (status
) == MAGIC_STAT
)
1283 exit (EX_SYSTEM
); /* Child had trouble */
1285 if (WEXITSTATUS (status
) == (SIGPIPE
+ 128))
1288 * /bin/sh returns this if its child
1289 * dies with SIGPIPE. 'Sok.
1293 else if (WEXITSTATUS (status
))
1294 msg ("child returned status %d",
1295 WEXITSTATUS (status
));
1299 #endif /* __MSDOS__ */
1305 * Message management.
1307 * anno writes a message prefix on stream (eg stdout, stderr).
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.
1313 * If the specified prefix is NULL, no output is produced unless the
1314 * command line option(s) are set.
1316 * If the third argument is 1, the "saved" record # is used; if 0, the
1317 * "current" record # is used.
1320 anno (stream
, prefix
, savedp
)
1326 char buffer
[MAXANNO
]; /* Holds annorecment */
1327 # define ANNOWIDTH 13
1333 /* Make sure previous output gets out in sequence */
1334 if (stream
== stderr
)
1340 fputs (prefix
, stream
);
1343 offset
= ar_record
- ar_block
;
1344 (void) sprintf (buffer
, "rec %d: ",
1345 savedp
? saved_recno
:
1347 fputs (buffer
, stream
);
1348 space
= ANNOWIDTH
- strlen (buffer
);
1351 fprintf (stream
, "%*s", space
, "");
1356 fputs (prefix
, stream
);
1357 fputs (": ", stream
);
1364 /* Called to initialize the global volume number. */
1366 init_volume_number ()
1370 vf
= fopen (f_volno_file
, "r");
1371 if (!vf
&& errno
!= ENOENT
)
1372 msg_perror ("%s", f_volno_file
);
1376 fscanf (vf
, "%d", &global_volno
);
1381 /* Called to write out the closing global volume number. */
1383 closeout_volume_number ()
1387 vf
= fopen (f_volno_file
, "w");
1389 msg_perror ("%s", f_volno_file
);
1392 fprintf (vf
, "%d\n", global_volno
);
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 */
1406 static FILE *read_file
= 0;
1407 extern int now_verifying
;
1408 extern char TTY_NAME
[];
1409 static int looped
= 0;
1411 if (!read_file
&& !f_run_script_at_end
)
1412 read_file
= (archive
== 0) ? fopen (TTY_NAME
, "r") : stdin
;
1418 if ((c
= rmtclose (archive
)) < 0)
1419 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1424 if (cur_ar_file
== n_ar_files
)
1433 /* We have to prompt from now on. */
1434 if (f_run_script_at_end
)
1435 system (info_script
);
1439 fprintf (msg_file
, "\007Prepare volume #%d for %s and hit return: ", global_volno
, ar_files
[cur_ar_file
]);
1441 if (fgets (inbuf
, sizeof (inbuf
), read_file
) == 0)
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!");
1448 if (inbuf
[0] == '\n' || inbuf
[0] == 'y' || inbuf
[0] == 'Y')
1455 fprintf (msg_file
, "\
1456 n [name] Give a new filename for the next (and subsequent) volume(s)\n\
1458 ! Spawn a subshell\n\
1459 ? Print this list\n");
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!");
1469 case 'n': /* Get new file name */
1472 static char *old_name
;
1474 for (q
= &inbuf
[1]; *q
== ' ' || *q
== '\t'; q
++)
1476 for (r
= q
; *r
; r
++)
1479 old_name
= p
= (char *) malloc ((unsigned) (strlen (q
) + 2));
1482 msg ("Can't allocate memory for name");
1485 (void) strcpy (p
, q
);
1486 ar_files
[cur_ar_file
] = p
;
1492 spawnl (P_WAIT
, getenv ("COMSPEC"), "-", 0);
1494 /* JF this needs work! */
1498 msg_perror ("can't fork!");
1501 p
= getenv ("SHELL");
1504 execlp (p
, "-sh", "-i", 0);
1505 msg_perror ("can't exec a shell %s", p
);
1518 if (type
== 2 || f_verify
)
1519 archive
= rmtopen (ar_files
[cur_ar_file
], O_RDWR
| O_CREAT
, 0666);
1521 archive
= rmtopen (ar_files
[cur_ar_file
], O_RDONLY
, 0666);
1523 archive
= rmtcreat (ar_files
[cur_ar_file
], 0666);
1529 msg_perror ("can't open %s", ar_files
[cur_ar_file
]);
1533 setmode (archive
, O_BINARY
);
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
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.
1556 wantbytes (size
, func
)
1565 data
= findrec ()->charptr
;
1568 msg ("Unexpected EOF on archive file");
1571 data_size
= endofrecs ()->charptr
- data
;
1572 if (data_size
> size
)
1574 if ((*func
) (data_size
, data
))
1576 userec ((union record
*) (data
+ data_size
- 1));
This page took 0.096982 seconds and 5 git commands to generate.