]>
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 compression program");
447 msg ("write to compression program short %d bytes",
449 count
= (err
< 0) ? 0 : err
;
464 ptr
= ar_block
->charptr
;
467 err
= read (STDIN
, ptr
, (n
< RECORDSIZE
) ? n
: RECORDSIZE
);
476 if (!f_compress_block
)
479 bzero (ar_block
->charptr
+ blocksize
- n
, n
);
480 err
= rmtwrite (archive
, ar_block
->charptr
, blocksize
);
481 if (err
!= (blocksize
))
483 if (!f_compress_block
)
489 msg_perror ("can't read from compression program");
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 (f_compressprog
, f_compressprog
, "-d", (char *) 0);
506 execlp (f_compressprog
, f_compressprog
, (char *) 0);
507 msg_perror ("can't exec %s", f_compressprog
);
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 current_file_name
= ar_block
->header
.arch_name
;
702 ar_block
->header
.linkflag
= LF_VOLHDR
;
703 to_oct (time (0), 1 + 12, ar_block
->header
.mtime
);
704 finish_header (ar_block
);
711 * Remember a union record * as pointing to something that we
712 * need to keep when reading onward in the file. Only one such
713 * thing can be remembered at once, and it only works when reading
716 * We calculate "offset" then add it because some compilers end up
717 * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
718 * subtracting ar_block from that, shifting it back, losing the top 9 bits.
722 union record
**pointer
;
727 offset
= ar_record
- ar_block
;
728 saved_recno
= baserec
+ offset
;
732 * Perform a write to flush the buffer.
735 /*send_buffer_to_file();
737 deal_with_new_volume_stuff();
738 send_buffer_to_file();
747 static long bytes_written
= 0;
749 if (f_checkpoint
&& !(++checkpoint
% 10))
750 msg ("Write checkpoint %d\n", checkpoint
);
751 if (tape_length
&& bytes_written
>= tape_length
* 1024)
757 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
758 if (err
!= blocksize
&& !f_multivol
)
761 tot_written
+= blocksize
;
764 bytes_written
+= err
;
765 if (err
== blocksize
)
771 real_s_name
[0] = '\0';
777 if (save_name
[1] == ':')
780 while (*save_name
== '/')
783 strcpy (real_s_name
, save_name
);
784 real_s_totsize
= save_totsize
;
785 real_s_sizeleft
= save_sizeleft
;
790 /* We're multivol Panic if we didn't get the right kind of response */
791 /* ENXIO is for the UNIX PC */
792 if (err
< 0 && errno
!= ENOSPC
&& errno
!= EIO
&& errno
!= ENXIO
)
795 /* If error indicates a short write, we just move to the next tape. */
797 if (new_volume (0) < 0)
800 if (f_volhdr
&& real_s_name
[0])
805 else if (f_volhdr
|| real_s_name
[0])
814 bzero ((void *) ar_block
, RECORDSIZE
);
815 sprintf (ar_block
->header
.arch_name
, "%s Volume %d", f_volhdr
, volno
);
816 to_oct (time (0), 1 + 12, ar_block
->header
.mtime
);
817 ar_block
->header
.linkflag
= LF_VOLHDR
;
818 finish_header (ar_block
);
826 bzero ((void *) ar_block
, RECORDSIZE
);
827 strcpy (ar_block
->header
.arch_name
, real_s_name
);
828 ar_block
->header
.linkflag
= LF_MULTIVOL
;
829 to_oct ((long) real_s_sizeleft
, 1 + 12,
830 ar_block
->header
.size
);
831 to_oct ((long) real_s_totsize
- real_s_sizeleft
,
832 1 + 12, ar_block
->header
.offset
);
835 finish_header (ar_block
);
841 err
= rmtwrite (archive
, ar_block
->charptr
, (int) blocksize
);
842 if (err
!= blocksize
)
845 tot_written
+= blocksize
;
848 bytes_written
= blocksize
;
851 ar_block
+= copy_back
;
852 bcopy ((void *) (ar_block
+ blocking
- copy_back
),
854 copy_back
* RECORDSIZE
);
855 ar_record
+= copy_back
;
857 if (real_s_sizeleft
>= copy_back
* RECORDSIZE
)
858 real_s_sizeleft
-= copy_back
* RECORDSIZE
;
859 else if ((real_s_sizeleft
+ RECORDSIZE
- 1) / RECORDSIZE
<= copy_back
)
860 real_s_name
[0] = '\0';
864 if (save_name
[1] == ':')
867 while (*save_name
== '/')
870 strcpy (real_s_name
, save_name
);
871 real_s_sizeleft
= save_sizeleft
;
872 real_s_totsize
= save_totsize
;
878 /* Handle write errors on the archive. Write errors are always fatal */
879 /* Hitting the end of a volume does not cause a write error unless the write
880 * was the first block of the volume */
888 msg_perror ("can't write to %s", ar_files
[cur_ar_file
]);
893 msg ("only wrote %u of %u bytes to %s", err
, blocksize
, ar_files
[cur_ar_file
]);
899 * Handle read errors on the archive.
901 * If the read should be retried, readerror() returns to the caller.
906 # define READ_ERROR_MAX 10
908 read_error_flag
++; /* Tell callers */
910 msg_perror ("read error on %s", ar_files
[cur_ar_file
]);
914 /* First block of tape. Probably stupidity error */
919 * Read error in mid archive. We retry up to READ_ERROR_MAX times
920 * and then give up on reading the archive. We set read_error_flag
921 * for our callers, so they can cope if they want.
923 if (r_error_count
++ > READ_ERROR_MAX
)
925 msg ("Too many errors, quitting.");
933 * Perform a read to flush the buffer.
938 int err
; /* Result from system call */
939 int left
; /* Bytes left */
940 char *more
; /* Pointer to next byte to read */
942 if (f_checkpoint
&& !(++checkpoint
% 10))
943 msg ("Read checkpoint %d\n", checkpoint
);
946 * Clear the count of errors. This only applies to a single
947 * call to fl_read. We leave read_error_flag alone; it is
948 * only turned off by higher level software.
950 r_error_count
= 0; /* Clear error count */
953 * If we are about to wipe out a record that
954 * somebody needs to keep, copy it out to a holding
955 * area and adjust somebody's pointer to it.
958 *save_rec
>= ar_record
&&
961 record_save_area
= **save_rec
;
962 *save_rec
= &record_save_area
;
964 if (write_archive_to_stdout
&& baserec
!= 0)
966 err
= rmtwrite (1, ar_block
->charptr
, blocksize
);
967 if (err
!= blocksize
)
974 if (save_name
!= real_s_name
)
977 if (save_name
[1] == ':')
980 while (*save_name
== '/')
983 strcpy (real_s_name
, save_name
);
984 save_name
= real_s_name
;
986 real_s_totsize
= save_totsize
;
987 real_s_sizeleft
= save_sizeleft
;
992 real_s_name
[0] = '\0';
999 err
= rmtread (archive
, ar_block
->charptr
, (int) blocksize
);
1000 if (err
== blocksize
)
1003 if ((err
== 0 || (err
< 0 && errno
== ENOSPC
) || (err
> 0 && !f_reblock
)) && f_multivol
)
1008 if (new_volume ((cmd_mode
== CMD_APPEND
|| cmd_mode
== CMD_CAT
|| cmd_mode
== CMD_UPDATE
) ? 2 : 1) < 0)
1011 err
= rmtread (archive
, ar_block
->charptr
, (int) blocksize
);
1017 if (err
!= blocksize
)
1022 if (head
->header
.linkflag
== LF_VOLHDR
)
1029 ptr
= (char *) malloc (strlen (f_volhdr
) + 20);
1030 sprintf (ptr
, "%s Volume %d", f_volhdr
, volno
);
1032 if (re_match (label_pattern
, head
->header
.arch_name
,
1033 strlen (head
->header
.arch_name
),
1036 msg ("Volume mismatch! %s!=%s", f_volhdr
,
1037 head
->header
.arch_name
);
1044 if (strcmp (ptr
, head
->header
.name
))
1046 msg ("Volume mismatch! %s!=%s", ptr
, head
->header
.name
);
1056 fprintf (msg_file
, "Reading %s\n", head
->header
.arch_name
);
1061 msg ("Warning: No volume header!");
1068 if (head
->header
.linkflag
!= LF_MULTIVOL
|| strcmp (head
->header
.arch_name
, real_s_name
))
1070 msg ("%s is not continued on this volume!", real_s_name
);
1075 if (real_s_totsize
!= from_oct (1 + 12, head
->header
.size
) + from_oct (1 + 12, head
->header
.offset
))
1077 msg ("%s is the wrong size (%ld!=%ld+%ld)",
1078 head
->header
.arch_name
, save_totsize
,
1079 from_oct (1 + 12, head
->header
.size
),
1080 from_oct (1 + 12, head
->header
.offset
));
1085 if (real_s_totsize
- real_s_sizeleft
!= from_oct (1 + 12, head
->header
.offset
))
1087 msg ("This volume is out of sequence");
1100 goto error_loop
; /* Try again */
1104 more
= ar_block
->charptr
+ err
;
1105 left
= blocksize
- err
;
1108 if (0 == (((unsigned) left
) % RECORDSIZE
))
1110 /* FIXME, for size=0, multi vol support */
1111 /* On the first block, warn about the problem */
1112 if (!f_reblock
&& baserec
== 0 && f_verbose
&& err
> 0)
1114 /* msg("Blocksize = %d record%s",
1115 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
1116 msg ("Blocksize = %d records", err
/ RECORDSIZE
);
1118 ar_last
= ar_block
+ ((unsigned) (blocksize
- left
)) / RECORDSIZE
;
1124 * User warned us about this. Fix up.
1129 err
= rmtread (archive
, more
, (int) left
);
1133 goto error2loop
; /* Try again */
1137 msg ("archive %s EOF not on block boundary", ar_files
[cur_ar_file
]);
1147 msg ("only read %d bytes from archive %s", err
, ar_files
[cur_ar_file
]);
1154 * Flush the current buffer to/from the archive.
1161 baserec
+= ar_last
- ar_block
;/* Keep track of block #s */
1162 ar_record
= ar_block
; /* Restore pointer to start */
1163 ar_last
= ar_block
+ blocking
;/* Restore pointer to end */
1167 if (time_to_start_writing
)
1169 time_to_start_writing
= 0;
1172 if (file_to_switch_to
>= 0)
1174 if ((c
= rmtclose (archive
)) < 0)
1175 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1177 archive
= file_to_switch_to
;
1180 (void) backspace_output ();
1192 /* Backspace the archive descriptor by one blocks worth.
1193 If its a tape, MTIOCTOP will work. If its something else,
1194 we try to seek on it. If we can't seek, we lose! */
1200 extern char *output_start
;
1207 if ((rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
1209 if (errno
== EIO
&& (rmtioctl (archive
, MTIOCTOP
, &t
)) >= 0)
1213 cur
= rmtlseek (archive
, 0L, 1);
1215 /* Seek back to the beginning of this block and
1216 start writing there. */
1218 if (rmtlseek (archive
, cur
, 0) != cur
)
1220 /* Lseek failed. Try a different method */
1221 msg ("Couldn't backspace archive file. It may be unreadable without -i.");
1222 /* Replace the first part of the block with nulls */
1223 if (ar_block
->charptr
!= output_start
)
1224 bzero (ar_block
->charptr
, output_start
- ar_block
->charptr
);
1232 * Close the archive file.
1241 if (time_to_start_writing
|| !ar_reading
)
1243 if (cmd_mode
== CMD_DELETE
)
1247 pos
= rmtlseek (archive
, 0L, 1);
1249 (void) ftruncate (archive
, pos
);
1251 (void) rmtwrite (archive
, "", 0);
1257 if ((c
= rmtclose (archive
)) < 0)
1258 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1264 * Loop waiting for the right child to die, or for
1267 while (((child
= wait (&status
)) != childpid
) && child
!= -1)
1272 if (WIFSIGNALED (status
))
1274 /* SIGPIPE is OK, everything else is a problem. */
1275 if (WTERMSIG (status
) != SIGPIPE
)
1276 msg ("child died with signal %d%s", WTERMSIG (status
),
1277 WIFCOREDUMPED (status
) ? " (core dumped)" : "");
1281 /* Child voluntarily terminated -- but why? */
1282 if (WEXITSTATUS (status
) == MAGIC_STAT
)
1284 exit (EX_SYSTEM
); /* Child had trouble */
1286 if (WEXITSTATUS (status
) == (SIGPIPE
+ 128))
1289 * /bin/sh returns this if its child
1290 * dies with SIGPIPE. 'Sok.
1294 else if (WEXITSTATUS (status
))
1295 msg ("child returned status %d",
1296 WEXITSTATUS (status
));
1300 #endif /* __MSDOS__ */
1306 * Message management.
1308 * anno writes a message prefix on stream (eg stdout, stderr).
1310 * The specified prefix is normally output followed by a colon and a space.
1311 * However, if other command line options are set, more output can come
1312 * out, such as the record # within the archive.
1314 * If the specified prefix is NULL, no output is produced unless the
1315 * command line option(s) are set.
1317 * If the third argument is 1, the "saved" record # is used; if 0, the
1318 * "current" record # is used.
1321 anno (stream
, prefix
, savedp
)
1327 char buffer
[MAXANNO
]; /* Holds annorecment */
1328 # define ANNOWIDTH 13
1334 /* Make sure previous output gets out in sequence */
1335 if (stream
== stderr
)
1341 fputs (prefix
, stream
);
1344 offset
= ar_record
- ar_block
;
1345 (void) sprintf (buffer
, "rec %d: ",
1346 savedp
? saved_recno
:
1348 fputs (buffer
, stream
);
1349 space
= ANNOWIDTH
- strlen (buffer
);
1352 fprintf (stream
, "%*s", space
, "");
1357 fputs (prefix
, stream
);
1358 fputs (": ", stream
);
1365 /* Called to initialize the global volume number. */
1367 init_volume_number ()
1371 vf
= fopen (f_volno_file
, "r");
1372 if (!vf
&& errno
!= ENOENT
)
1373 msg_perror ("%s", f_volno_file
);
1377 fscanf (vf
, "%d", &global_volno
);
1382 /* Called to write out the closing global volume number. */
1384 closeout_volume_number ()
1388 vf
= fopen (f_volno_file
, "w");
1390 msg_perror ("%s", f_volno_file
);
1393 fprintf (vf
, "%d\n", global_volno
);
1398 /* We've hit the end of the old volume. Close it and open the next one */
1399 /* Values for type: 0: writing 1: reading 2: updating */
1407 static FILE *read_file
= 0;
1408 extern int now_verifying
;
1409 extern char TTY_NAME
[];
1410 static int looped
= 0;
1412 if (!read_file
&& !f_run_script_at_end
)
1413 read_file
= (archive
== 0) ? fopen (TTY_NAME
, "r") : stdin
;
1419 if ((c
= rmtclose (archive
)) < 0)
1420 msg_perror ("Warning: can't close %s(%d,%d)", ar_files
[cur_ar_file
], archive
, c
);
1425 if (cur_ar_file
== n_ar_files
)
1434 /* We have to prompt from now on. */
1435 if (f_run_script_at_end
)
1437 closeout_volume_number ();
1438 system (info_script
);
1443 fprintf (msg_file
, "\007Prepare volume #%d for %s and hit return: ", global_volno
, ar_files
[cur_ar_file
]);
1445 if (fgets (inbuf
, sizeof (inbuf
), read_file
) == 0)
1447 fprintf (msg_file
, "EOF? What does that mean?");
1448 if (cmd_mode
!= CMD_EXTRACT
&& cmd_mode
!= CMD_LIST
&& cmd_mode
!= CMD_DIFF
)
1449 msg ("Warning: Archive is INCOMPLETE!");
1452 if (inbuf
[0] == '\n' || inbuf
[0] == 'y' || inbuf
[0] == 'Y')
1459 fprintf (msg_file
, "\
1460 n [name] Give a new filename for the next (and subsequent) volume(s)\n\
1462 ! Spawn a subshell\n\
1463 ? Print this list\n");
1467 case 'q': /* Quit */
1468 fprintf (msg_file
, "No new volume; exiting.\n");
1469 if (cmd_mode
!= CMD_EXTRACT
&& cmd_mode
!= CMD_LIST
&& cmd_mode
!= CMD_DIFF
)
1470 msg ("Warning: Archive is INCOMPLETE!");
1473 case 'n': /* Get new file name */
1476 static char *old_name
;
1478 for (q
= &inbuf
[1]; *q
== ' ' || *q
== '\t'; q
++)
1480 for (r
= q
; *r
; r
++)
1483 old_name
= p
= (char *) malloc ((unsigned) (strlen (q
) + 2));
1486 msg ("Can't allocate memory for name");
1489 (void) strcpy (p
, q
);
1490 ar_files
[cur_ar_file
] = p
;
1496 spawnl (P_WAIT
, getenv ("COMSPEC"), "-", 0);
1498 /* JF this needs work! */
1502 msg_perror ("can't fork!");
1505 p
= getenv ("SHELL");
1508 execlp (p
, "-sh", "-i", 0);
1509 msg_perror ("can't exec a shell %s", p
);
1522 if (type
== 2 || f_verify
)
1523 archive
= rmtopen (ar_files
[cur_ar_file
], O_RDWR
| O_CREAT
, 0666);
1525 archive
= rmtopen (ar_files
[cur_ar_file
], O_RDONLY
, 0666);
1527 archive
= rmtcreat (ar_files
[cur_ar_file
], 0666);
1533 msg_perror ("can't open %s", ar_files
[cur_ar_file
]);
1537 setmode (archive
, O_BINARY
);
1542 /* this is a useless function that takes a buffer returned by wantbytes
1543 and does nothing with it. If the function called by wantbytes returns
1544 an error indicator (non-zero), this function is called for the rest of
1555 /* Some other routine wants SIZE bytes in the archive. For each chunk of
1556 the archive, call FUNC with the size of the chunk, and the address of
1557 the chunk it can work with.
1560 wantbytes (size
, func
)
1569 data
= findrec ()->charptr
;
1572 msg ("Unexpected EOF on archive file");
1575 data_size
= endofrecs ()->charptr
- data
;
1576 if (data_size
> size
)
1578 if ((*func
) (data_size
, data
))
1580 userec ((union record
*) (data
+ data_size
- 1));
This page took 0.097791 seconds and 5 git commands to generate.