- switch (head->header.linkflag) {
-
- default:
- msg("Unknown file type '%c' for %s, extracted as normal file",
- head->header.linkflag, skipcrud+head->header.name);
- /* FALL THRU */
-
- /*
- * JK - What we want to do if the file is sparse is loop through
- * the array of sparse structures in the header and read in
- * and translate the character strings representing 1) the offset
- * at which to write and 2) how many bytes to write into numbers,
- * which we store into the scratch array, "sparsearray". This
- * array makes our life easier the same way it did in creating
- * the tar file that had to deal with a sparse file.
- *
- * After we read in the first five (at most) sparse structures,
- * we check to see if the file has an extended header, i.e.,
- * if more sparse structures are needed to describe the contents
- * of the new file. If so, we read in the extended headers
- * and continue to store their contents into the sparsearray.
- */
- case LF_SPARSE:
- sp_array_size = 10;
- sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));
- for (i = 0; i < SPARSE_IN_HDR; i++) {
- sparsearray[i].offset =
- from_oct(1+12, head->header.sp[i].offset);
- sparsearray[i].numbytes =
- from_oct(1+12, head->header.sp[i].numbytes);
- if (!sparsearray[i].numbytes)
- break;
- }
-
-/* end_nulls = from_oct(1+12, head->header.ending_blanks);*/
-
- if (head->header.isextended) {
- /* read in the list of extended headers
- and translate them into the sparsearray
- as before */
-
- /* static */ int ind = SPARSE_IN_HDR;
-
- for (;;) {
-
- exhdr = findrec();
- for (i = 0; i < SPARSE_EXT_HDR; i++) {
-
- if (i+ind > sp_array_size-1) {
- /*
- * realloc the scratch area
- * since we've run out of room --
- */
- sparsearray = (struct sp_array *)
- realloc(sparsearray,
- 2 * sp_array_size * (sizeof(struct sp_array)));
- sp_array_size *= 2;
- }
- if (!exhdr->ext_hdr.sp[i].numbytes)
- break;
- sparsearray[i+ind].offset =
- from_oct(1+12, exhdr->ext_hdr.sp[i].offset);
- sparsearray[i+ind].numbytes =
- from_oct(1+12, exhdr->ext_hdr.sp[i].numbytes);
- }
- if (!exhdr->ext_hdr.isextended)
- break;
- else {
- ind += SPARSE_EXT_HDR;
- userec(exhdr);
- }
- }
- userec(exhdr);
- }
-
- /* FALL THRU */
- case LF_OLDNORMAL:
- case LF_NORMAL:
- case LF_CONTIG:
- /*
- * Appears to be a file.
- * See if it's really a directory.
- */
- namelen = strlen(skipcrud+head->header.name)-1;
- if (head->header.name[skipcrud+namelen] == '/')
- goto really_dir;
-
- /* FIXME, deal with protection issues */
- again_file:
- openflag = (f_keep?
- O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_EXCL:
- O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC)
- | ((head->header.linkflag == LF_SPARSE) ? 0 : O_APPEND);
- /*
- * JK - The last | is a kludge to solve the problem
- * the O_APPEND flag causes with files we are
- * trying to make sparse: when a file is opened
- * with O_APPEND, it writes to the last place
- * that something was written, thereby ignoring
- * any lseeks that we have done. We add this
- * extra condition to make it able to lseek when
- * a file is sparse, i.e., we don't open the new
- * file with this flag. (Grump -- this bug caused
- * me to waste a good deal of time, I might add)
- */
-
- if(f_exstdout) {
- fd = 1;
- goto extract_file;
- }
-#ifdef O_CTG
- /*
- * Contiguous files (on the Masscomp) have to specify
- * the size in the open call that creates them.
- */
- if (head->header.linkflag == LF_CONTIG)
- fd = open(skipcrud+head->header.name, openflag | O_CTG,
- hstat.st_mode, hstat.st_size);
- else
-#endif
- {
-#ifdef NO_OPEN3
- /*
- * On raw V7 we won't let them specify -k (f_keep), but
- * we just bull ahead and create the files.
- */
- fd = creat(skipcrud+head->header.name,
- hstat.st_mode);
-#else
- /*
- * With 3-arg open(), we can do this up right.
- */
- fd = open(skipcrud+head->header.name, openflag,
- hstat.st_mode);
-#endif
- }