/* * Read the tape and write to stdout. */ void tarsnap_mode_r(struct bsdtar *bsdtar) { TAPE_R * d; const void * buf; ssize_t lenread; size_t writelen; /* Open the tape. */ if ((d = readtape_open(bsdtar->machinenum, bsdtar->tapenames[0])) == NULL) goto err1; /* Loop until we have an error or EOF. */ do { lenread = readtape_read(d, &buf); /* Error? */ if (lenread < 0) goto err2; /* EOF? */ if (lenread == 0) break; /* Output data to stdout. */ writelen = (size_t)(lenread); if (fwrite(buf, 1, writelen, stdout) != writelen) goto err2; } while (1); /* We're done! Close the tape. */ if (readtape_close(d)) goto err1; /* Success! */ return; err2: readtape_close(d); err1: /* Failure! */ bsdtar_warnc(bsdtar, 0, "Error reading archive"); exit(1); }
/** * archive_read_open_multitape(a, machinenum, tapename): * Open the multitape tape ${tapename} for reading (and skipping) and * associate it with the archive $a$. Return a cookie which can be passed * to the multitape layer. */ void * archive_read_open_multitape(struct archive * a, uint64_t machinenum, const char * tapename) { struct multitape_read_internal * d; /* Clear any error messages from the archive. */ archive_clear_error(a); if ((d = readtape_open(machinenum, tapename)) == NULL) { archive_set_error(a, errno, "Error opening archive"); return (NULL); } if (archive_read_open2(a, d, NULL, read_read, read_skip, read_close)) return (NULL); else return (d); }