]>
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
);
281 msg_perror ("cannot fork");
286 /* We're the parent. Clean up and be happy */
287 /* This, at least, is easy */
292 archive
= pipe
[READ
];
293 ck_close (pipe
[WRITE
]);
297 archive
= pipe
[WRITE
];
298 ck_close (pipe
[READ
]);
306 dupto (pipe
[WRITE
], STDOUT
, "(child) pipe to stdout");
307 ck_close (pipe
[READ
]);
311 dupto (pipe
[READ
], STDIN
, "(child) pipe to stdin");
312 ck_close (pipe
[WRITE
]);
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 */
320 if (!(ar_files
[0][0] == '-' && ar_files
[0][1] == '\0') && isfile (ar_files
[0]))
322 if (!(ar_files
[0][0] == '-' && ar_files
[0][1] == '\0') && !_remdev (ar_files
[0]) && isfile (ar_files
[0]))
325 /* We don't need a child tar. Open the archive */
328 archive
= open (ar_files
[0], O_RDONLY
| O_BINARY
, 0666);
331 msg_perror ("can't open archive %s", ar_files
[0]);
334 dupto (archive
, STDIN
, "archive to stdin");
335 /* close(archive); */
339 archive
= creat (ar_files
[0], 0666);
342 msg_perror ("can't open archive %s", ar_files
[0]);
345 dupto (archive
, STDOUT
, "archive to stdout");
346 /* close(archive); */
351 /* We need a child tar */
354 kidchildpid
= fork ();
357 msg_perror ("child can't fork");
363 /* About to exec compress: set up the files */
366 dupto (kidpipe
[READ
], STDIN
, "((child)) pipe to stdin");
367 ck_close (kidpipe
[WRITE
]);
368 /* dup2(pipe[WRITE],STDOUT); */
372 /* dup2(pipe[READ],STDIN); */
373 dupto (kidpipe
[WRITE
], STDOUT
, "((child)) pipe to stdout");
374 ck_close (kidpipe
[READ
]);
376 /* ck_close(pipe[READ]); */
377 /* ck_close(pipe[WRITE]); */
378 /* ck_close(kidpipe[READ]);
379 ck_close(kidpipe[WRITE]); */
383 /* Grandchild. Do the right thing, namely sit here and
384 read/write the archive, and feed stuff back to compress */
388 dupto (kidpipe
[WRITE
], STDOUT
, "[child] pipe to stdout");
389 ck_close (kidpipe
[READ
]);
393 dupto (kidpipe
[READ
], STDIN
, "[child] pipe to stdin");
394 ck_close (kidpipe
[WRITE
]);
397 if (ar_files
[0][0] == '-' && ar_files
[0][1] == '\0')
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);
409 archive
= rmtcreat (ar_files
[0], 0666);
413 msg_perror ("can't open archive %s", ar_files
[0]);
426 err
= rmtread (archive
, ar_block
->charptr
, (int) (blocksize
));
434 ptr
= ar_block
->charptr
;
438 count
= (max
< RECORDSIZE
) ? max
: RECORDSIZE
;
439 err
= write (STDOUT
, ptr
, count
);
444 msg_perror ("can't write to compress");
448 msg ("write to compress short %d bytes", count
- err
);
449 count
= (err
< 0) ? 0 : err
;
464 ptr
= ar_block
->charptr
;
467 err
= read (STDIN
, ptr
, (n
< RECORDSIZE
) ? n
: RECORDSIZE
);
479 bzero (ar_block
->charptr
+ blocksize
- n
, n
);
480 err
= rmtwrite (archive
, ar_block
->charptr
, blocksize
);
481 if (err
!= (blocksize
))
489 msg_perror ("can't read from compress");
492 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
493 if (err
!= blocksize
)
498 /* close_archive(); */
502 /* So we should exec compress (-d) */
504 execlp ("compress", "compress", "-d", (char *) 0);
506 execlp ("compress", "compress", (char *) 0);
507 msg_perror ("can't exec compress");
512 /* return non-zero if p is the name of a directory */
519 if (stat (p
, &stbuf
) < 0)
521 if (S_ISREG (stbuf
.st_mode
))
529 * Open an archive file. The argument specifies whether we are
530 * reading or writing.
532 /* JF if the arg is 2, open for reading and writing. */
534 open_archive (reading
)
537 msg_file
= f_exstdout
? stderr
: stdout
;
541 msg ("invalid value for blocksize");
547 msg ("No archive name given, what should I do?");
554 ar_block
= (union record
*) valloc ((unsigned) (blocksize
+ (2 * RECORDSIZE
)));
559 ar_block
= (union record
*) valloc ((unsigned) blocksize
);
562 msg ("could not allocate memory for blocking factor %d",
567 ar_record
= ar_block
;
568 ar_last
= ar_block
+ blocking
;
569 ar_reading
= reading
;
571 if (f_multivol
&& f_verify
)
573 msg ("cannot verify multi-volume archives");
579 if (reading
== 2 || f_verify
)
581 msg ("cannot update or verify compressed archives");
586 msg ("cannot use multi-volume compressed archives");
590 if (!reading
&& ar_files
[0][0] == '-' && ar_files
[0][1] == '\0')
592 /* child_open(rem_host, rem_file); */
594 else if (ar_files
[0][0] == '-' && ar_files
[0][1] == '\0')
596 f_reblock
++; /* Could be a pipe, be safe */
599 msg ("can't verify stdin/stdout archive");
606 write_archive_to_stdout
++;
616 else if (reading
== 2 || f_verify
)
618 archive
= rmtopen (ar_files
[0], O_RDWR
| O_CREAT
| O_BINARY
, 0666);
622 archive
= rmtopen (ar_files
[0], O_RDONLY
| O_BINARY
, 0666);
626 archive
= rmtcreat (ar_files
[0], 0666);
630 msg_perror ("can't open %s", ar_files
[0]);
634 if (!_isrmt (archive
))
636 struct stat tmp_stat
;
638 fstat (archive
, &tmp_stat
);
639 if (S_ISREG (tmp_stat
.st_mode
))
641 ar_dev
= tmp_stat
.st_dev
;
642 ar_ino
= tmp_stat
.st_ino
;
648 setmode (archive
, O_BINARY
);
653 ar_last
= ar_block
; /* Set up for 1st block = # 0 */
654 (void) findrec (); /* Read it in, check for EOF */
664 ptr
= malloc (strlen (f_volhdr
) + 20);
665 sprintf (ptr
, "%s Volume %d", f_volhdr
, 1);
673 msg ("Archive not labelled to match %s", f_volhdr
);
676 if (re_match (label_pattern
, head
->header
.arch_name
,
677 strlen (head
->header
.arch_name
), 0, 0) < 0)
679 msg ("Volume mismatch! %s!=%s", f_volhdr
,
680 head
->header
.arch_name
);
684 if (strcmp (ptr
, head
->header
.name
))
686 msg ("Volume mismatch! %s!=%s", ptr
, head
->header
.name
);
696 bzero ((void *) ar_block
, RECORDSIZE
);
698 sprintf (ar_block
->header
.arch_name
, "%s Volume 1", f_volhdr
);
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
);
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
);
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.096444 seconds and 5 git commands to generate.