if (AH->lookahead)
free(AH->lookahead);
+ AH->readHeader = 0;
AH->lookaheadSize = 512;
AH->lookahead = pg_malloc0(512);
AH->lookaheadLen = 0;
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
{
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)
exit_horribly(modulename, "could not close input file: %s\n",
strerror(errno));
+ /* Forget lookahead, since we'll re-read header after re-opening */
+ AH->readHeader = 0;
+ AH->lookaheadLen = 0;
+ }
return AH->format;
}
void
ReadHead(ArchiveHandle *AH)
{
- char tmpMag[7];
+ char vmaj,
+ vmin,
+ vrev;
int fmt;
struct tm crtm;
*/
if (!AH->readHeader)
{
- char vmaj,
- vmin,
- vrev;
+ char tmpMag[7];
(*AH->ReadBufPtr) (AH, tmpMag, 5);
if (strncmp(tmpMag, "PGDMP", 5) != 0)
exit_horribly(modulename, "did not find magic string in file header\n");
+ }
- 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)
- exit_horribly(modulename, "unsupported version (%d.%d) in file header\n",
- vmaj, vmin);
+ if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
+ exit_horribly(modulename, "unsupported version (%d.%d) in file header\n",
+ vmaj, vmin);
- AH->intSize = (*AH->ReadBytePtr) (AH);
- if (AH->intSize > 32)
- exit_horribly(modulename, "sanity check on integer size (%lu) failed\n",
- (unsigned long) AH->intSize);
+ AH->intSize = (*AH->ReadBytePtr) (AH);
+ if (AH->intSize > 32)
+ exit_horribly(modulename, "sanity check on integer size (%lu) failed\n",
+ (unsigned long) AH->intSize);
- if (AH->intSize > sizeof(int))
- write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n");
+ if (AH->intSize > sizeof(int))
+ write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n");
- 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)
- exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n",
- AH->format, fmt);
- }
+ if (AH->format != fmt)
+ exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n",
+ AH->format, fmt);
if (AH->version >= K_VERS_1_2)
{
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