- /*
- * This is not a link to a previously dumped file, so dump it.
- */
- if (S_ISREG(hstat.st_mode)
-#ifdef S_ISCTG
- || S_ISCTG(hstat.st_mode)
-#endif
- )
- {
- int f; /* File descriptor */
- long bufsize, count;
- long sizeleft;
- register union record *start;
- int header_moved;
- char isextended = 0;
- int upperbound;
-/* int end_nulls = 0; */
-
- header_moved = 0;
-
-#ifdef BSD42
- if (f_sparse_files) {
- /*
- * JK - This is the test for sparseness: whether the
- * "size" of the file matches the number of blocks
- * allocated for it. If there is a smaller number
- * of blocks that would be necessary to accommodate
- * a file of this size, we have a sparse file, i.e.,
- * at least one of those records in the file is just
- * a useless hole.
- */
-#ifdef hpux /* Nice of HPUX to gratuitiously change it, huh? - mib */
- if (hstat.st_size - (hstat.st_blocks * 1024) > 1024 )
-#else
- if (hstat.st_size - (hstat.st_blocks * RECORDSIZE) > RECORDSIZE)
-#endif
- {
- int filesize = hstat.st_size;
- register int i;
-
- header = start_header(p, &hstat);
- if (header == NULL)
- {
- critical_error = 1;
- goto badfile;
- }
- header->header.linkflag = LF_SPARSE;
- header_moved++;
-
- /*
- * Call the routine that figures out the
- * layout of the sparse file in question.
- * UPPERBOUND is the index of the last
- * element of the "sparsearray," i.e.,
- * the number of elements it needed to
- * describe the file.
- */
-
- upperbound = deal_with_sparse(p, header);
-
- /*
- * See if we'll need an extended header
- * later
- */
- if (upperbound > SPARSE_IN_HDR-1)
- header->header.isextended++;
- /*
- * We store the "real" file size so
- * we can show that in case someone wants
- * to list the archive, i.e., tar tvf <file>.
- * It might be kind of disconcerting if the
- * shrunken file size was the one that showed
- * up.
- */
- to_oct((long) hstat.st_size, 1+12,
- header->header.realsize);
-
- /*
- * This will be the new "size" of the
- * file, i.e., the size of the file
- * minus the records of holes that we're
- * skipping over.
- */
-
- find_new_file_size(&filesize, upperbound);
- hstat.st_size = filesize;
- to_oct((long) filesize, 1+12,
- header->header.size);
-/* to_oct((long) end_nulls, 1+12,
- header->header.ending_blanks);*/
-
- for (i = 0; i < SPARSE_IN_HDR; i++) {
- if (!sparsearray[i].numbytes)
- break;
- to_oct(sparsearray[i].offset, 1+12,
- header->header.sp[i].offset);
- to_oct(sparsearray[i].numbytes, 1+12,
- header->header.sp[i].numbytes);
- }
-
- }
- }
-#else
- upperbound=SPARSE_IN_HDR-1;
-#endif
-
- sizeleft = hstat.st_size;
- /* Don't bother opening empty, world readable files. */
- if (sizeleft > 0 || 0444 != (0444 & hstat.st_mode)) {
- f = open(p, O_RDONLY|O_BINARY);
- if (f < 0) goto badperror;
- } else {
- f = -1;
- }
-
- /* If the file is sparse, we've already taken care of this */
- if (!header_moved) {
- header = start_header(p, &hstat);
- if (header == NULL) {
- if(f>=0)
- (void)close(f);
- critical_error = 1;
- goto badfile;
- }
- }
-#ifdef S_ISCTG
- /* Mark contiguous files, if we support them */
- if (f_standard && S_ISCTG(hstat.st_mode)) {
- header->header.linkflag = LF_CONTIG;
- }
-#endif
- isextended = header->header.isextended;
- save_linkflag = header->header.linkflag;
- finish_header(header);
- if (isextended) {
-/* int sum = 0;*/
- register int i;
-/* register union record *exhdr;*/
-/* int arraybound = SPARSE_EXT_HDR;*/
- /* static */ int index_offset = SPARSE_IN_HDR;
-
- extend: exhdr = findrec();
-
- if (exhdr == NULL)
- {
- critical_error = 1;
- goto badfile;
- }
- bzero(exhdr->charptr, RECORDSIZE);
- for (i = 0; i < SPARSE_EXT_HDR; i++) {
- if (i+index_offset > upperbound)
- break;
- to_oct((long) sparsearray[i+index_offset].numbytes,
- 1+12,
- exhdr->ext_hdr.sp[i].numbytes);
- to_oct((long) sparsearray[i+index_offset].offset,
- 1+12,
- exhdr->ext_hdr.sp[i].offset);
- }
- userec(exhdr);
-/* sum += i;
- if (sum < upperbound)
- goto extend;*/
- if (index_offset+i < upperbound) {
- index_offset += i;
- exhdr->ext_hdr.isextended++;
- goto extend;
- }
-
- }
- if (save_linkflag == LF_SPARSE) {
- if (finish_sparse_file(f, &sizeleft, hstat.st_size, p))
- goto padit;
- }
- else
- while (sizeleft > 0) {
-
- if(f_multivol) {
- save_name = p;
- save_sizeleft = sizeleft;
- save_totsize = hstat.st_size;
- }
- start = findrec();
-
- bufsize = endofrecs()->charptr - start->charptr;
-
- if (sizeleft < bufsize) {
- /* Last read -- zero out area beyond */
- bufsize = (int)sizeleft;
- count = bufsize % RECORDSIZE;
- if (count)
- bzero(start->charptr + sizeleft,
- (int)(RECORDSIZE - count));
- }
- count = read(f, start->charptr, bufsize);
- if (count < 0) {
- msg_perror("read error at byte %ld, reading\
- %d bytes, in file %s", hstat.st_size - sizeleft, bufsize,p);
- goto padit;
- }
- sizeleft -= count;