1 /* Buffer management for tar.
2 Copyright (C) 1988 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 */
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();
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 /* JF we're reading, but we just read the last record and its time to update */
131 extern time_to_start_writing;
132 int file_to_switch_to= -1; /* If remote update, close archive, and use
133 this descriptor to write to */
135 static int volno = 1; /* JF which volume of a multi-volume tape
138 char *save_name = 0; /* Name of the file we are currently writing */
139 long save_totsize; /* total size of file we are writing. Only
140 valid if save_name is non_zero */
141 long save_sizeleft; /* Where we are in the file we are writing.
142 Only valid if save_name is non-zero */
144 int write_archive_to_stdout;
146 /* Used by fl_read and fl_write to store the real info about saved names */
147 static char real_s_name[NAMSIZ];
148 static long real_s_totsize;
149 static long real_s_sizeleft;
151 /* Reset the EOF flag (if set), and re-set ar_record, etc */
159 ar_last=ar_block+blocking;
165 * Return the location of the next available input or output record.
166 * Return NULL for EOF. Once we have returned NULL, we just keep returning
167 * it, to avoid accidentally going on to the next file on the "tape".
172 if (ar_record == ar_last) {
174 return (union record *)NULL; /* EOF */
176 if (ar_record == ar_last) {
178 return (union record *)NULL; /* EOF */
186 * Indicate that we have used all records up thru the argument.
187 * (should the arg have an off-by-1? XXX FIXME)
193 while(rec >= ar_record)
196 * Do NOT flush the archive here. If we do, the same
197 * argument to userec() could mean the next record (if the
198 * input block is exactly one record long), which is not what
201 if (ar_record > ar_last)
207 * Return a pointer to the end of the current records buffer.
208 * All the space between findrec() and endofrecs() is available
209 * for filling with data, or taking data from.
219 * Duplicate a file descriptor into a certain slot.
220 * Equivalent to BSD "dup2" with error reporting.
231 if(err<0 && errno!=EBADF) {
232 msg_perror("Cannot close descriptor %d",to);
237 msg_perror("cannot dup %s",msg);
248 fprintf(stderr,"MS-DOS %s can't use compressed or remote archives\n",tar);
268 msg_perror("cannot fork");
272 /* We're the parent. Clean up and be happy */
273 /* This, at least, is easy */
278 ck_close(pipe[WRITE]);
280 archive = pipe[WRITE];
281 ck_close(pipe[READ]);
288 dupto(pipe[WRITE],STDOUT,"(child) pipe to stdout");
289 ck_close(pipe[READ]);
291 dupto(pipe[READ],STDIN,"(child) pipe to stdin");
292 ck_close(pipe[WRITE]);
295 /* We need a child tar only if
296 1: we're reading/writing stdin/out (to force reblocking)
297 2: the file is to be accessed by rmt (compress doesn't know how)
298 3: the file is not a plain file */
300 if(!(ar_file[0]=='-' && ar_file[1]=='\0') && isfile(ar_file))
302 if(!(ar_file[0]=='-' && ar_file[1]=='\0') && !_remdev(ar_file) && isfile(ar_file))
305 /* We don't need a child tar. Open the archive */
307 archive=open(ar_file, O_RDONLY|O_BINARY, 0666);
309 msg_perror("can't open archive %s",ar_file);
312 dupto(archive,STDIN,"archive to stdin");
313 /* close(archive); */
315 archive=creat(ar_file,0666);
317 msg_perror("can't open archive %s",ar_file);
320 dupto(archive,STDOUT,"archive to stdout");
321 /* close(archive); */
324 /* We need a child tar */
329 msg_perror("child can't fork");
334 /* About to exec compress: set up the files */
336 dupto(kidpipe[READ],STDIN,"((child)) pipe to stdin");
337 ck_close(kidpipe[WRITE]);
338 /* dup2(pipe[WRITE],STDOUT); */
340 /* dup2(pipe[READ],STDIN); */
341 dupto(kidpipe[WRITE],STDOUT,"((child)) pipe to stdout");
342 ck_close(kidpipe[READ]);
344 /* ck_close(pipe[READ]); */
345 /* ck_close(pipe[WRITE]); */
346 /* ck_close(kidpipe[READ]);
347 ck_close(kidpipe[WRITE]); */
349 /* Grandchild. Do the right thing, namely sit here and
350 read/write the archive, and feed stuff back to compress */
353 dupto(kidpipe[WRITE],STDOUT,"[child] pipe to stdout");
354 ck_close(kidpipe[READ]);
356 dupto(kidpipe[READ],STDIN,"[child] pipe to stdin");
357 ck_close(kidpipe[WRITE]);
360 if (ar_file[0] == '-' && ar_file[1] == '\0') {
365 } else /* This can't happen if (ar_reading==2)
366 archive = rmtopen(ar_file, O_RDWR|O_CREAT|O_BINARY, 0666);
367 else */if(ar_reading)
368 archive = rmtopen(ar_file, O_RDONLY|O_BINARY, 0666);
370 archive = rmtcreat(ar_file, 0666);
373 msg_perror("can't open archive %s",ar_file);
384 err=rmtread(archive, ar_block->charptr,(int)(blocksize));
391 ptr = ar_block->charptr;
394 count = (max<RECORDSIZE) ? max : RECORDSIZE;
395 err=write(STDOUT,ptr,count);
398 msg_perror("can't write to compress");
401 msg("write to compress short %d bytes",count-err);
402 count = (err<0) ? 0 : err;
414 ptr = ar_block->charptr;
416 err=read(STDIN,ptr,(n<RECORDSIZE) ? n : RECORDSIZE);
427 bzero(ar_block->charptr+blocksize-n,n);
428 err=rmtwrite(archive,ar_block->charptr,blocksize);
436 msg_perror("can't read from compress");
439 err=rmtwrite(archive, ar_block->charptr, (int)blocksize);
445 /* close_archive(); */
449 /* So we should exec compress (-d) */
451 execlp("compress", "compress", "-d", (char *)0);
453 execlp("compress", "compress", (char *)0);
454 msg_perror("can't exec compress");
459 /* return non-zero if p is the name of a directory */
468 if(S_ISREG(stbuf.st_mode))
476 * Open an archive file. The argument specifies whether we are
477 * reading or writing.
479 /* JF if the arg is 2, open for reading and writing. */
481 open_archive(reading)
484 msg_file = f_exstdout ? stderr : stdout;
486 if (blocksize == 0) {
487 msg("invalid value for blocksize");
492 msg("No archive name given, what should I do?");
498 ar_block = (union record *) valloc((unsigned)(blocksize+(2*RECORDSIZE)));
502 ar_block = (union record *) valloc((unsigned)blocksize);
504 msg("could not allocate memory for blocking factor %d",
509 ar_record = ar_block;
510 ar_last = ar_block + blocking;
511 ar_reading = reading;
514 if(reading==2 || f_verify) {
515 msg("cannot update or verify compressed archives");
519 if(!reading && ar_file[0]=='-' && ar_file[1]=='\0')
521 /* child_open(rem_host, rem_file); */
522 } else if (ar_file[0] == '-' && ar_file[1] == '\0') {
523 f_reblock++; /* Could be a pipe, be safe */
525 msg("can't verify stdin/stdout archive");
531 write_archive_to_stdout++;
538 } else if (reading==2 || f_verify) {
539 archive = rmtopen(ar_file, O_RDWR|O_CREAT|O_BINARY, 0666);
541 archive = rmtopen(ar_file, O_RDONLY|O_BINARY, 0666);
543 archive = rmtcreat(ar_file, 0666);
546 msg_perror("can't open %s",ar_file);
551 if(!_isrmt(archive)) {
552 struct stat tmp_stat;
554 fstat(archive,&tmp_stat);
555 if(S_ISREG(tmp_stat.st_mode)) {
556 ar_dev=tmp_stat.st_dev;
557 ar_ino=tmp_stat.st_ino;
563 setmode(archive, O_BINARY);
567 ar_last = ar_block; /* Set up for 1st block = # 0 */
568 (void) findrec(); /* Read it in, check for EOF */
576 ptr=malloc(strlen(f_volhdr)+20);
577 sprintf(ptr,"%s Volume %d",f_volhdr,1);
583 msg("Archive not labelled to match %s",f_volhdr);
586 if (re_match (label_pattern, head->header.name,
587 strlen (head->header.name), 0, 0) < 0) {
588 msg ("Volume mismatch! %s!=%s", f_volhdr,
593 if(strcmp(ptr,head->header.name)) {
594 msg("Volume mismatch! %s!=%s",ptr,head->header.name);
601 } else if(f_volhdr) {
602 bzero((void *)ar_block,RECORDSIZE);
604 sprintf(ar_block->header.name,"%s Volume 1",f_volhdr);
606 strcpy(ar_block->header.name,f_volhdr);
607 ar_block->header.linkflag = LF_VOLHDR;
608 to_oct(time(0), 1+12, ar_block->header.mtime);
609 finish_header(ar_block);
616 * Remember a union record * as pointing to something that we
617 * need to keep when reading onward in the file. Only one such
618 * thing can be remembered at once, and it only works when reading
621 * We calculate "offset" then add it because some compilers end up
622 * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
623 * subtracting ar_block from that, shifting it back, losing the top 9 bits.
627 union record **pointer;
632 offset = ar_record - ar_block;
633 saved_recno = baserec + offset;
637 * Perform a write to flush the buffer.
640 /*send_buffer_to_file();
642 deal_with_new_volume_stuff();
643 send_buffer_to_file();
652 static long bytes_written = 0;
654 if(tape_length && bytes_written >= tape_length * 1024) {
658 err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
659 if(err!=blocksize && !f_multivol)
662 tot_written += blocksize;
666 if (err == blocksize) {
675 if(save_name[1]==':')
678 while(*save_name=='/')
681 strcpy(real_s_name,save_name);
682 real_s_totsize = save_totsize;
683 real_s_sizeleft = save_sizeleft;
688 /* We're multivol Panic if we didn't get the right kind of response */
689 /* ENXIO is for the UNIX PC */
690 if(err>0 || (err<0 && errno!=ENOSPC && errno!=EIO && errno!=ENXIO))
696 if(f_volhdr && real_s_name[0]) {
699 } else if(f_volhdr || real_s_name[0]) {
705 bzero((void *)ar_block,RECORDSIZE);
706 sprintf(ar_block->header.name,"%s Volume %d",f_volhdr,volno);
707 to_oct(time(0), 1+12, ar_block->header.mtime);
708 ar_block->header.linkflag = LF_VOLHDR;
709 finish_header(ar_block);
716 bzero((void *)ar_block,RECORDSIZE);
717 strcpy(ar_block->header.name,real_s_name);
718 ar_block->header.linkflag = LF_MULTIVOL;
719 to_oct((long)real_s_sizeleft,1+12,
720 ar_block->header.size);
721 to_oct((long)real_s_totsize-real_s_sizeleft,
722 1+12,ar_block->header.offset);
725 finish_header(ar_block);
731 err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
735 tot_written += blocksize;
738 bytes_written = blocksize;
741 bcopy((void *)(ar_block+blocking-copy_back),
743 copy_back*RECORDSIZE);
744 ar_record+=copy_back;
746 if(real_s_sizeleft>=copy_back*RECORDSIZE)
747 real_s_sizeleft-=copy_back*RECORDSIZE;
748 else if((real_s_sizeleft+RECORDSIZE-1)/RECORDSIZE<=copy_back)
749 real_s_name[0] = '\0';
752 if(save_name[1]==':')
755 while(*save_name=='/')
758 strcpy(real_s_name,save_name);
759 real_s_sizeleft = save_sizeleft;
760 real_s_totsize=save_totsize;
766 /* Handle write errors on the archive. Write errors are always fatal */
767 /* Hitting the end of a volume does not cause a write error unless the write
768 * was the first block of the volume */
775 msg_perror("can't write to %s",ar_file);
778 msg("only wrote %u of %u bytes to %s",err,blocksize,ar_file);
784 * Handle read errors on the archive.
786 * If the read should be retried, readerror() returns to the caller.
791 # define READ_ERROR_MAX 10
793 read_error_flag++; /* Tell callers */
795 msg_perror("read error on %s",ar_file);
798 /* First block of tape. Probably stupidity error */
803 * Read error in mid archive. We retry up to READ_ERROR_MAX times
804 * and then give up on reading the archive. We set read_error_flag
805 * for our callers, so they can cope if they want.
807 if (r_error_count++ > READ_ERROR_MAX) {
808 msg("Too many errors, quitting.");
816 * Perform a read to flush the buffer.
821 int err; /* Result from system call */
822 int left; /* Bytes left */
823 char *more; /* Pointer to next byte to read */
826 * Clear the count of errors. This only applies to a single
827 * call to fl_read. We leave read_error_flag alone; it is
828 * only turned off by higher level software.
830 r_error_count = 0; /* Clear error count */
833 * If we are about to wipe out a record that
834 * somebody needs to keep, copy it out to a holding
835 * area and adjust somebody's pointer to it.
838 *save_rec >= ar_record &&
839 *save_rec < ar_last) {
840 record_save_area = **save_rec;
841 *save_rec = &record_save_area;
843 if(write_archive_to_stdout && baserec!=0) {
844 err=rmtwrite(1, ar_block->charptr, blocksize);
850 if(save_name!=real_s_name) {
852 if(save_name[1]==':')
855 while(*save_name=='/')
858 strcpy(real_s_name,save_name);
859 save_name=real_s_name;
861 real_s_totsize = save_totsize;
862 real_s_sizeleft = save_sizeleft;
872 err = rmtread(archive, ar_block->charptr, (int)blocksize);
873 if (err == blocksize)
876 if((err == 0 || (err<0 && errno==ENOSPC)) && f_multivol) {
880 if(new_volume((cmd_mode==CMD_APPEND || cmd_mode==CMD_CAT || cmd_mode==CMD_UPDATE) ? 2 : 1)<0)
883 err = rmtread(archive, ar_block->charptr,(int) blocksize);
893 if(head->header.linkflag==LF_VOLHDR) {
898 ptr=(char *)malloc(strlen(f_volhdr)+20);
899 sprintf(ptr,"%s Volume %d",f_volhdr,volno);
901 if (re_match (label_pattern, head->header.name,
902 strlen (head->header.name),
904 msg("Volume mismatch! %s!=%s",f_volhdr,
911 if(strcmp(ptr,head->header.name)) {
912 msg("Volume mismatch! %s!=%s",ptr,head->header.name);
921 fprintf(msg_file,"Reading %s\n",head->header.name);
923 } else if(f_volhdr) {
924 msg("Warning: No volume header!");
930 if(head->header.linkflag!=LF_MULTIVOL || strcmp(head->header.name,real_s_name)) {
931 msg("%s is not continued on this volume!",real_s_name);
935 if(real_s_totsize!=from_oct(1+12,head->header.size)+from_oct(1+12,head->header.offset)) {
936 msg("%s is the wrong size (%ld!=%ld+%ld)",
937 head->header.name,save_totsize,
938 from_oct(1+12,head->header.size),
939 from_oct(1+12,head->header.offset));
943 if(real_s_totsize-real_s_sizeleft!=from_oct(1+12,head->header.offset)) {
944 msg("This volume is out of sequence");
952 } else if (err < 0) {
954 goto error_loop; /* Try again */
958 more = ar_block->charptr + err;
959 left = blocksize - err;
962 if (0 == (((unsigned)left) % RECORDSIZE)) {
963 /* FIXME, for size=0, multi vol support */
964 /* On the first block, warn about the problem */
965 if (!f_reblock && baserec == 0 && f_verbose && err > 0) {
966 /* msg("Blocksize = %d record%s",
967 err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
968 msg("Blocksize = %d records", err / RECORDSIZE);
970 ar_last = ar_block + ((unsigned)(blocksize - left))/RECORDSIZE;
975 * User warned us about this. Fix up.
979 err = rmtread(archive, more, (int)left);
982 goto error2loop; /* Try again */
985 msg("archive %s EOF not on block boundary",ar_file);
993 msg("only read %d bytes from archive %s",err,ar_file);
1000 * Flush the current buffer to/from the archive.
1007 baserec += ar_last - ar_block; /* Keep track of block #s */
1008 ar_record = ar_block; /* Restore pointer to start */
1009 ar_last = ar_block + blocking; /* Restore pointer to end */
1012 if(time_to_start_writing) {
1013 time_to_start_writing=0;
1016 if(file_to_switch_to>=0) {
1017 if((c=rmtclose(archive))<0)
1018 msg_perror("Warning: can't close %s(%d,%d)",ar_file,archive,c);
1020 archive=file_to_switch_to;
1022 (void)backspace_output();
1031 /* Backspace the archive descriptor by one blocks worth.
1032 If its a tape, MTIOCTOP will work. If its something else,
1033 we try to seek on it. If we can't seek, we lose! */
1039 extern char *output_start;
1046 if((rmtioctl(archive,MTIOCTOP,&t))>=0)
1048 if(errno==EIO && (rmtioctl(archive,MTIOCTOP,&t))>=0)
1052 cur=rmtlseek(archive,0L,1);
1054 /* Seek back to the beginning of this block and
1055 start writing there. */
1057 if(rmtlseek(archive,cur,0)!=cur) {
1058 /* Lseek failed. Try a different method */
1059 msg("Couldn't backspace archive file. It may be unreadable without -i.");
1060 /* Replace the first part of the block with nulls */
1061 if(ar_block->charptr!=output_start)
1062 bzero(ar_block->charptr,output_start-ar_block->charptr);
1070 * Close the archive file.
1079 if (time_to_start_writing || !ar_reading)
1081 if(cmd_mode==CMD_DELETE) {
1084 pos = rmtlseek(archive,0L,1);
1086 (void) ftruncate(archive,pos);
1088 (void)rmtwrite(archive,"",0);
1094 if((c=rmtclose(archive))<0)
1095 msg_perror("Warning: can't close %s(%d,%d)",ar_file,archive,c);
1100 * Loop waiting for the right child to die, or for
1103 while (((child = wait(&status)) != childpid) && child != -1)
1107 switch (WTERMSIG(status)) {
1109 /* Child voluntarily terminated -- but why? */
1110 if (WEXITSTATUS(status) == MAGIC_STAT) {
1111 exit(EX_SYSTEM);/* Child had trouble */
1113 if (WEXITSTATUS(status) == (SIGPIPE + 128)) {
1115 * /bin/sh returns this if its child
1116 * dies with SIGPIPE. 'Sok.
1119 } else if (WEXITSTATUS(status))
1120 msg("child returned status %d",
1121 WEXITSTATUS(status));
1123 break; /* This is OK. */
1126 msg("child died with signal %d%s",
1128 WIFCOREDUMPED(status)? " (core dumped)": "");
1132 #endif /* __MSDOS__ */
1138 * Message management.
1140 * anno writes a message prefix on stream (eg stdout, stderr).
1142 * The specified prefix is normally output followed by a colon and a space.
1143 * However, if other command line options are set, more output can come
1144 * out, such as the record # within the archive.
1146 * If the specified prefix is NULL, no output is produced unless the
1147 * command line option(s) are set.
1149 * If the third argument is 1, the "saved" record # is used; if 0, the
1150 * "current" record # is used.
1153 anno(stream, prefix, savedp)
1159 char buffer[MAXANNO]; /* Holds annorecment */
1160 # define ANNOWIDTH 13
1166 /* Make sure previous output gets out in sequence */
1167 if (stream == stderr)
1171 fputs(prefix, stream);
1174 offset = ar_record - ar_block;
1175 (void) sprintf(buffer, "rec %d: ",
1176 savedp? saved_recno:
1178 fputs(buffer, stream);
1179 space = ANNOWIDTH - strlen(buffer);
1181 fprintf(stream, "%*s", space, "");
1183 } else if (prefix) {
1184 fputs(prefix, stream);
1185 fputs(": ", stream);
1191 /* We've hit the end of the old volume. Close it and open the next one */
1192 /* Values for type: 0: writing 1: reading 2: updating */
1200 static FILE *read_file = 0;
1201 extern int now_verifying;
1202 extern char TTY_NAME[];
1205 if(!read_file && !f_run_script_at_end)
1206 read_file = (archive==0) ? fopen(TTY_NAME, "r") : stdin;
1212 if((c=rmtclose(archive))<0)
1213 msg_perror("Warning: can't close %s(%d,%d)",ar_file,archive,c);
1217 if (f_run_script_at_end)
1218 system(info_script);
1220 fprintf(msg_file,"\007Prepare volume #%d and hit return: ",volno);
1222 if(fgets(inbuf,sizeof(inbuf),read_file)==0) {
1223 fprintf(msg_file,"EOF? What does that mean?");
1224 if(cmd_mode!=CMD_EXTRACT && cmd_mode!=CMD_LIST && cmd_mode!=CMD_DIFF)
1225 msg("Warning: Archive is INCOMPLETE!");
1228 if(inbuf[0]=='\n' || inbuf[0]=='y' || inbuf[0]=='Y')
1235 n [name] Give a new filename for the next (and subsequent) volume(s)\n\
1237 ! Spawn a subshell\n\
1238 ? Print this list\n");
1242 case 'q': /* Quit */
1243 fprintf(msg_file,"No new volume; exiting.\n");
1244 if(cmd_mode!=CMD_EXTRACT && cmd_mode!=CMD_LIST && cmd_mode!=CMD_DIFF)
1245 msg("Warning: Archive is INCOMPLETE!");
1248 case 'n': /* Get new file name */
1251 static char *old_name;
1253 for(q= &inbuf[1];*q==' ' || *q=='\t';q++)
1260 old_name=p=(char *)malloc((unsigned)(strlen(q)+2));
1262 msg("Can't allocate memory for name");
1272 spawnl(P_WAIT,getenv("COMSPEC"),"-",0);
1274 /* JF this needs work! */
1277 msg_perror("can't fork!");
1281 if(p==0) p="/bin/sh";
1282 execlp(p,"-sh","-i",0);
1283 msg_perror("can't exec a shell %s",p);
1294 if(type==2 || f_verify)
1295 archive=rmtopen(ar_file,O_RDWR|O_CREAT,0666);
1297 archive=rmtopen(ar_file,O_RDONLY,0666);
1299 archive=rmtcreat(ar_file,0666);
1304 msg_perror("can't open %s",ar_file);
1308 setmode(archive,O_BINARY);
1313 /* this is a useless function that takes a buffer returned by wantbytes
1314 and does nothing with it. If the function called by wantbytes returns
1315 an error indicator (non-zero), this function is called for the rest of
1326 /* Some other routine wants SIZE bytes in the archive. For each chunk of
1327 the archive, call FUNC with the size of the chunk, and the address of
1328 the chunk it can work with.
1331 wantbytes(size,func)
1339 data = findrec()->charptr;
1340 if (data == NULL) { /* Check it... */
1341 msg("Unexpected EOF on archive file");
1344 data_size = endofrecs()->charptr - data;
1347 if((*func)(data_size,data))
1349 userec((union record *)(data + data_size - 1));