- for (rec->state=0; !is_block_empty(rec); ) {
- if (!read_record_from_block(block, rec)) {
- break;
- }
-
- /* This is no longer used */
- if (rec->VolSessionId == 0 && rec->VolSessionTime == 0) {
- Emsg0(M_ERROR, 0, "Zero header record. This shouldn't happen.\n");
- break; /* END OF FILE */
- }
-
- /*
- * Check for Start or End of Session Record
- *
- */
- if (rec->FileIndex < 0) {
- char *rtype;
- memset(&sessrec, 0, sizeof(sessrec));
- switch (rec->FileIndex) {
- case PRE_LABEL:
- rtype = "Fresh Volume Label";
- break;
- case VOL_LABEL:
- rtype = "Volume Label";
- unser_volume_label(dev, rec);
- break;
- case SOS_LABEL:
- rtype = "Begin Session";
- unser_session_label(&sessrec, rec);
- break;
- case EOS_LABEL:
- rtype = "End Session";
- break;
- case EOM_LABEL:
- rtype = "End of Media";
- break;
- default:
- rtype = "Unknown";
- break;
- }
- if (debug_level > 0) {
- printf("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
- rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
- }
-
- Dmsg1(40, "Got label = %d\n", rec->FileIndex);
- if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
- Dmsg0(40, "Get EOM LABEL\n");
- break; /* yes, get out */
- }
- continue; /* ignore other labels */
- } /* end if label record */
-
- /* Is this the file we want? */
- if (bsr && !match_bsr(bsr, rec, &dev->VolHdr, &sessrec)) {
- rec->remainder = 0;
- continue;
- }
- if (is_partial_record(rec)) {
- break;
- }
-
- /* File Attributes stream */
- if (rec->Stream == STREAM_UNIX_ATTRIBUTES) {
- char *ap, *lp, *fp;
-
- /* If extracting, it was from previous stream, so
- * close the output file.
- */
- if (extract) {
- if (ofd < 0) {
- Emsg0(M_ERROR_TERM, 0, "Logic error output file should be open\n");
- }
- close(ofd);
- ofd = -1;
- extract = FALSE;
- set_statp(jcr, fname, ofile, lname, type, &statp);
- }
-
- if (sizeof_pool_memory(fname) < rec->data_len) {
- fname = realloc_pool_memory(fname, rec->data_len + 1);
- }
- if (sizeof_pool_memory(ofile) < sizeof_pool_memory(fname) + wherelen + 1) {
- ofile = realloc_pool_memory(ofile, sizeof_pool_memory(fname) + wherelen + 1);
- }
- if (sizeof_pool_memory(lname) < rec->data_len) {
- lname = realloc_pool_memory(lname, rec->data_len + 1);
- }
- *fname = 0;
- *lname = 0;
-
- /*
- * An Attributes record consists of:
- * File_index
- * Type (FT_types)
- * Filename
- * Attributes
- * Link name (if file linked i.e. FT_LNK)
- *
- */
- sscanf(rec->data, "%ld %d", &record_file_index, &type);
- if (record_file_index != rec->FileIndex)
- Emsg2(M_ERROR_TERM, 0, "Record header file index %ld not equal record index %ld\n",
- rec->FileIndex, record_file_index);
- ap = rec->data;
- while (*ap++ != ' ') /* skip record file index */
- ;
- while (*ap++ != ' ') /* skip type */
- ;
- /* Save filename and position to attributes */
- fp = fname;
- while (*ap != 0) {
- *fp++ = *ap++;
- }
- *fp = *ap++; /* terminate filename & point to attribs */
-
- /* Skip to Link name */
- if (type == FT_LNK) {
- lp = ap;
- while (*lp++ != 0) {
- ;
- }
- strcat(lname, lp); /* "save" link name */
- } else {
- *lname = 0;
- }
-
-
- if (file_is_included(ff, fname) && !file_is_excluded(ff, fname)) {
-
- decode_stat(ap, &statp);
- /*
- * Prepend the where directory so that the
- * files are put where the user wants.
- *
- * We do a little jig here to handle Win32 files with
- * a drive letter.
- * If where is null and we are running on a win32 client,
- * change nothing.
- * Otherwise, if the second character of the filename is a
- * colon (:), change it into a slash (/) -- this creates
- * a reasonable pathname on most systems.
- */
- strcpy(ofile, where);
- if (fname[1] == ':') {
- fname[1] = '/';
- strcat(ofile, fname);
- fname[1] = ':';
- } else {
- strcat(ofile, fname);
- }
- /* Pmsg1(000, "Restoring: %s\n", ofile); */
-
- extract = create_file(jcr, fname, ofile, lname, type, &statp, &ofd);
-
- if (extract) {
- print_ls_output(ofile, lname, type, &statp);
- }
- }
-
- /* Data stream and extracting */
- } else if (rec->Stream == STREAM_FILE_DATA) {
- if (extract) {
- total += rec->data_len;
- Dmsg2(8, "Write %ld bytes, total=%ld\n", rec->data_len, total);
- if ((uint32_t)write(ofd, rec->data, rec->data_len) != rec->data_len) {
- Emsg1(M_ERROR_TERM, 0, "Write error: %s\n", strerror(errno));
- }
- }
-
- } else if (rec->Stream == STREAM_GZIP_DATA) {
-#ifdef HAVE_LIBZ
- if (extract) {
- uLongf compress_len;
-
- compress_len = compress_buf_size;
- if (uncompress((Bytef *)compress_buf, &compress_len,
- (const Bytef *)rec->data, (uLong)rec->data_len) != Z_OK) {
- Emsg0(M_ERROR_TERM, 0, _("Uncompression error.\n"));
- }
-
- Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
- if ((uLongf)write(ofd, compress_buf, (size_t)compress_len) != compress_len) {
- Pmsg0(0, "===Write error===\n");
- Emsg2(M_ERROR_TERM, 0, "Write error on %s: %s\n", ofile, strerror(errno));
- }
- total += compress_len;
- Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
- compress_len);
- }
-#else
- if (extract) {
- Emsg0(M_ERROR_TERM, 0, "GZIP data stream found, but GZIP not configured!\n");
- }
-#endif