diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/pg_dump/pg_backup_archiver.c | 137 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_backup_archiver.h | 18 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_backup_tar.c | 6 |
3 files changed, 51 insertions, 110 deletions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 0ac8b187be5..86de26a4bf0 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -2071,6 +2071,7 @@ _discoverArchiveFormat(ArchiveHandle *AH) if (AH->lookahead) free(AH->lookahead); + AH->readHeader = 0; AH->lookaheadSize = 512; AH->lookahead = pg_malloc0(512); AH->lookaheadLen = 0; @@ -2142,62 +2143,9 @@ _discoverArchiveFormat(ArchiveHandle *AH) if (strncmp(sig, "PGDMP", 5) == 0) { - int byteread; - char vmaj, - vmin, - vrev; - - /* - * Finish reading (most of) a custom-format header. - * - * NB: this code must agree with ReadHead(). - */ - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - vmaj = byteread; - - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - vmin = byteread; - - /* Save these too... */ - AH->lookahead[AH->lookaheadLen++] = vmaj; - AH->lookahead[AH->lookaheadLen++] = vmin; - - /* Check header version; varies from V1.0 */ - if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */ - { - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - vrev = byteread; - AH->lookahead[AH->lookaheadLen++] = vrev; - } - else - vrev = 0; - - AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); - - if ((AH->intSize = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - AH->lookahead[AH->lookaheadLen++] = AH->intSize; - - if (AH->version >= K_VERS_1_7) - { - if ((AH->offSize = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - AH->lookahead[AH->lookaheadLen++] = AH->offSize; - } - else - AH->offSize = AH->intSize; - - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - AH->format = byteread; - AH->lookahead[AH->lookaheadLen++] = AH->format; + /* It's custom format, stop here */ + AH->format = archCustom; + AH->readHeader = 1; } else { @@ -2234,22 +2182,15 @@ _discoverArchiveFormat(ArchiveHandle *AH) AH->format = archTar; } - /* If we can't seek, then mark the header as read */ - if (fseeko(fh, 0, SEEK_SET) != 0) - { - /* - * NOTE: Formats that use the lookahead buffer can unset this in their - * Init routine. - */ - AH->readHeader = 1; - } - else - AH->lookaheadLen = 0; /* Don't bother since we've reset the file */ - - /* Close the file */ + /* Close the file if we opened it */ if (wantClose) + { if (fclose(fh) != 0) fatal("could not close input file: %m"); + /* Forget lookahead, since we'll re-read header after re-opening */ + AH->readHeader = 0; + AH->lookaheadLen = 0; + } return AH->format; } @@ -3790,7 +3731,9 @@ WriteHead(ArchiveHandle *AH) void ReadHead(ArchiveHandle *AH) { - char tmpMag[7]; + char vmaj, + vmin, + vrev; int fmt; struct tm crtm; @@ -3802,48 +3745,46 @@ ReadHead(ArchiveHandle *AH) */ if (!AH->readHeader) { - char vmaj, - vmin, - vrev; + char tmpMag[7]; AH->ReadBufPtr(AH, tmpMag, 5); if (strncmp(tmpMag, "PGDMP", 5) != 0) fatal("did not find magic string in file header"); + } - vmaj = AH->ReadBytePtr(AH); - vmin = AH->ReadBytePtr(AH); + vmaj = AH->ReadBytePtr(AH); + vmin = AH->ReadBytePtr(AH); - if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */ - vrev = AH->ReadBytePtr(AH); - else - vrev = 0; + if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */ + vrev = AH->ReadBytePtr(AH); + else + vrev = 0; - AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); + AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); - if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) - fatal("unsupported version (%d.%d) in file header", - vmaj, vmin); + if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) + fatal("unsupported version (%d.%d) in file header", + vmaj, vmin); - AH->intSize = AH->ReadBytePtr(AH); - if (AH->intSize > 32) - fatal("sanity check on integer size (%lu) failed", - (unsigned long) AH->intSize); + AH->intSize = AH->ReadBytePtr(AH); + if (AH->intSize > 32) + fatal("sanity check on integer size (%lu) failed", + (unsigned long) AH->intSize); - if (AH->intSize > sizeof(int)) - pg_log_warning("archive was made on a machine with larger integers, some operations might fail"); + if (AH->intSize > sizeof(int)) + pg_log_warning("archive was made on a machine with larger integers, some operations might fail"); - if (AH->version >= K_VERS_1_7) - AH->offSize = AH->ReadBytePtr(AH); - else - AH->offSize = AH->intSize; + if (AH->version >= K_VERS_1_7) + AH->offSize = AH->ReadBytePtr(AH); + else + AH->offSize = AH->intSize; - fmt = AH->ReadBytePtr(AH); + fmt = AH->ReadBytePtr(AH); - if (AH->format != fmt) - fatal("expected format (%d) differs from format found in file (%d)", - AH->format, fmt); - } + if (AH->format != fmt) + fatal("expected format (%d) differs from format found in file (%d)", + AH->format, fmt); if (AH->version >= K_VERS_1_2) { diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index 9d0f03d5629..2fdc0d341f3 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -253,15 +253,21 @@ struct _archiveHandle time_t createDate; /* Date archive created */ /* - * Fields used when discovering header. A format can always get the - * previous read bytes from here... + * Fields used when discovering archive format. For tar format, we load + * the first block into the lookahead buffer, and verify that it looks + * like a tar header. The tar module must then consume bytes from the + * lookahead buffer before reading any more from the file. For custom + * format, we load only the "PGDMP" marker into the buffer, and then set + * readHeader after confirming it matches. The buffer is vestigial in + * this case, as the subsequent code just checks readHeader and doesn't + * examine the buffer. */ - int readHeader; /* Used if file header has been read already */ + int readHeader; /* Set if we already read "PGDMP" marker */ char *lookahead; /* Buffer used when reading header to discover * format */ - size_t lookaheadSize; /* Size of allocated buffer */ - size_t lookaheadLen; /* Length of data in lookahead */ - pgoff_t lookaheadPos; /* Current read position in lookahead buffer */ + size_t lookaheadSize; /* Allocated size of buffer */ + size_t lookaheadLen; /* Length of valid data in lookahead */ + size_t lookaheadPos; /* Current read position in lookahead buffer */ ArchiveEntryPtrType ArchiveEntryPtr; /* Called for each metadata object */ StartDataPtrType StartDataPtr; /* Called when table data is about to be diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 54e708875cd..b773ed0cb82 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -228,12 +228,6 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) ctx->hasSeek = checkSeek(ctx->tarFH); - /* - * Forcibly unmark the header as read since we use the lookahead - * buffer - */ - AH->readHeader = 0; - ctx->FH = (void *) tarOpen(AH, "toc.dat", 'r'); ReadHead(AH); ReadToc(AH); |