*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.58 2002/10/16 05:46:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.59 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
}
ahprintf(AH, "; Dump Version: %d.%d-%d\n", AH->vmaj, AH->vmin, AH->vrev);
- ahprintf(AH, "; Format: %s\n;\n", fmtName);
+ ahprintf(AH, "; Format: %s\n", fmtName);
+ ahprintf(AH, "; Integer: %d bytes\n", AH->intSize);
+ ahprintf(AH, "; Offset: %d bytes\n", AH->offSize);
- ahprintf(AH, ";\n; Selected TOC Entries:\n;\n");
+ ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
while (te != AH->toc)
{
return _tocEntryRequired(te, ropt);
}
+size_t
+WriteOffset(ArchiveHandle *AH, off_t o, int wasSet)
+{
+ int off;
+
+ /* Save the flag */
+ (*AH->WriteBytePtr) (AH, wasSet);
+
+ /* Write out off_t smallest byte first, prevents endian mismatch */
+ for (off = 0; off < sizeof(off_t); off++)
+ {
+ (*AH->WriteBytePtr) (AH, o & 0xFF);
+ o >>= 8;
+ }
+ return sizeof(off_t) + 1;
+}
+
+int
+ReadOffset(ArchiveHandle *AH, off_t *o)
+{
+ int i;
+ int off;
+ int offsetFlg;
+
+ /* Initialize to zero */
+ *o = 0;
+
+ /* Check for old version */
+ if (AH->version < K_VERS_1_7)
+ {
+ /* Prior versions wrote offsets using WriteInt */
+ i = ReadInt(AH);
+ /* -1 means not set */
+ if (i < 0)
+ return K_OFFSET_POS_NOT_SET;
+ else if (i == 0)
+ return K_OFFSET_NO_DATA;
+
+ /* Cast to off_t because it was written as an int. */
+ *o = (off_t)i;
+ return K_OFFSET_POS_SET;
+ }
+
+ /*
+ * Read the flag indicating the state of the data pointer.
+ * Check if valid and die if not.
+ *
+ * This used to be handled by a negative or zero pointer,
+ * now we use an extra byte specifically for the state.
+ */
+ offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF;
+
+ switch (offsetFlg)
+ {
+ case K_OFFSET_POS_NOT_SET:
+ case K_OFFSET_NO_DATA:
+ case K_OFFSET_POS_SET:
+
+ break;
+
+ default:
+ die_horribly(AH, modulename, "Unexpected data offset flag %d\n", offsetFlg);
+ }
+
+ /*
+ * Read the bytes
+ */
+ for (off = 0; off < AH->offSize; off++)
+ {
+ if (off < sizeof(off_t))
+ *o |= ((*AH->ReadBytePtr) (AH)) << (off * 8);
+ else
+ {
+ if ((*AH->ReadBytePtr) (AH) != 0)
+ die_horribly(AH, modulename, "file offset in dump file is too large\n");
+ }
+ }
+
+ return offsetFlg;
+}
+
size_t
WriteInt(ArchiveHandle *AH, int i)
{
else
AH->vrev = 0;
+ /* Make a convenient integer <maj><min><rev>00 */
+ AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
+
AH->intSize = fgetc(fh);
AH->lookahead[AH->lookaheadLen++] = AH->intSize;
+ if (AH->version >= K_VERS_1_7)
+ {
+ AH->offSize = fgetc(fh);
+ AH->lookahead[AH->lookaheadLen++] = AH->offSize;
+ }
+ else
+ AH->offSize = AH->intSize;
+
AH->format = fgetc(fh);
AH->lookahead[AH->lookaheadLen++] = AH->format;
-
- /* Make a convenient integer <maj><min><rev>00 */
- AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
}
else
{
if (!AH)
die_horribly(AH, modulename, "out of memory\n");
+ /* AH->debugLevel = 100; */
+
AH->vmaj = K_VERS_MAJOR;
AH->vmin = K_VERS_MINOR;
AH->vrev = K_VERS_REV;
AH->createDate = time(NULL);
AH->intSize = sizeof(int);
+ AH->offSize = sizeof(off_t);
AH->lastID = 0;
if (FileSpec)
{
/* Sanity check */
if (te->id <= 0 || te->id > AH->tocCount)
- die_horribly(AH, modulename, "entry id out of range - perhaps a corrupt TOC\n");
+ die_horribly(AH, modulename, "entry id %d out of range - perhaps a corrupt TOC\n", te->id);
te->hadDumper = ReadInt(AH);
te->oid = ReadStr(AH);
(*AH->WriteBytePtr) (AH, AH->vmin);
(*AH->WriteBytePtr) (AH, AH->vrev);
(*AH->WriteBytePtr) (AH, AH->intSize);
+ (*AH->WriteBytePtr) (AH, AH->offSize);
(*AH->WriteBytePtr) (AH, AH->format);
#ifndef HAVE_LIBZ
if (AH->intSize > sizeof(int))
write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations may fail\n");
+ if (AH->version >= K_VERS_1_7)
+ AH->offSize = (*AH->ReadBytePtr) (AH);
+ else
+ AH->offSize = AH->intSize;
+
fmt = (*AH->ReadBytePtr) (AH);
if (AH->format != fmt)
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.47 2002/09/04 20:31:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.48 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "libpq-fe.h"
#define K_VERS_MAJOR 1
-#define K_VERS_MINOR 6
+#define K_VERS_MINOR 7
#define K_VERS_REV 0
/* Data block types */
#define K_VERS_1_4 (( (1 * 256 + 4) * 256 + 0) * 256 + 0) /* Date & name in header */
#define K_VERS_1_5 (( (1 * 256 + 5) * 256 + 0) * 256 + 0) /* Handle dependencies */
#define K_VERS_1_6 (( (1 * 256 + 6) * 256 + 0) * 256 + 0) /* Schema field in TOCs */
-#define K_VERS_MAX (( (1 * 256 + 6) * 256 + 255) * 256 + 0)
+#define K_VERS_1_7 (( (1 * 256 + 7) * 256 + 0) * 256 + 0) /* File Offset size in header */
+#define K_VERS_MAX (( (1 * 256 + 7) * 256 + 255) * 256 + 0)
/* No of BLOBs to restore in 1 TX */
#define BLOB_BATCH_SIZE 100
+/* Flags to indicate disposition of offsets stored in files */
+#define K_OFFSET_POS_NOT_SET 1
+#define K_OFFSET_POS_SET 2
+#define K_OFFSET_NO_DATA 3
+
struct _archiveHandle;
struct _tocEntry;
struct _restoreList;
int debugLevel; /* Used for logging (currently only by
* --verbose) */
size_t intSize; /* Size of an integer in the archive */
+ size_t offSize; /* Size of a file offset in the archive - Added V1.7 */
ArchiveFormat format; /* Archive format */
sqlparseInfo sqlparse;
extern char *ReadStr(ArchiveHandle *AH);
extern size_t WriteStr(ArchiveHandle *AH, const char *s);
+int ReadOffset(ArchiveHandle*, off_t*);
+size_t WriteOffset(ArchiveHandle*, off_t, int);
+
extern void StartRestoreBlobs(ArchiveHandle *AH);
extern void StartRestoreBlob(ArchiveHandle *AH, Oid oid);
extern void EndRestoreBlob(ArchiveHandle *AH, Oid oid);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.21 2002/09/04 20:31:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.22 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
typedef struct
{
+ int dataState;
off_t dataPos;
- size_t dataLen;
} lclTocEntry;
*/
if (AH->mode == archModeWrite)
{
-
if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
AH->FH = fopen(AH->fSpec, PG_BINARY_W);
else
die_horribly(AH, modulename, "could not open archive file %s: %s\n", AH->fSpec, strerror(errno));
ctx->hasSeek = (fseeko(AH->FH, 0, SEEK_CUR) == 0);
-
}
else
{
-
if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
AH->FH = fopen(AH->fSpec, PG_BINARY_R);
else
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry));
if (te->dataDumper)
- ctx->dataPos = -1;
+ ctx->dataState = K_OFFSET_POS_NOT_SET;
else
- ctx->dataPos = 0;
- ctx->dataLen = 0;
- te->formatData = (void *) ctx;
+ ctx->dataState = K_OFFSET_NO_DATA;
+ te->formatData = (void *) ctx;
}
/*
{
lclTocEntry *ctx = (lclTocEntry *) te->formatData;
- WriteInt(AH, ctx->dataPos);
- WriteInt(AH, ctx->dataLen);
+ WriteOffset(AH, ctx->dataPos, ctx->dataState);
}
/*
static void
_ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
{
+ int junk;
lclTocEntry *ctx = (lclTocEntry *) te->formatData;
if (ctx == NULL)
te->formatData = (void *) ctx;
}
- ctx->dataPos = ReadInt(AH);
- ctx->dataLen = ReadInt(AH);
+ ctx->dataState = ReadOffset(AH, &(ctx->dataPos) );
+
+ /*
+ * Prior to V1.7 (pg7.3), we dumped the data size as an int
+ * now we don't dump it at all.
+ */
+ if (AH->version < K_VERS_1_7)
+ junk = ReadInt(AH);
}
/*
{
lclTocEntry *ctx = (lclTocEntry *) te->formatData;
- ahprintf(AH, "-- Data Pos: " INT64_FORMAT " (Length %lu)\n",
- (int64) ctx->dataPos, (unsigned long) ctx->dataLen);
+ ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
+ (int64) ctx->dataPos);
}
/*
lclTocEntry *tctx = (lclTocEntry *) te->formatData;
tctx->dataPos = _getFilePos(AH, ctx);
+ tctx->dataState = K_OFFSET_POS_SET;
_WriteByte(AH, BLK_DATA); /* Block type */
WriteInt(AH, te->id); /* For sanity check */
_StartDataCompressor(AH, te);
-
}
/*
static void
_EndData(ArchiveHandle *AH, TocEntry *te)
{
- lclContext *ctx = (lclContext *) AH->formatData;
- lclTocEntry *tctx = (lclTocEntry *) te->formatData;
+/* lclContext *ctx = (lclContext *) AH->formatData; */
+/* lclTocEntry *tctx = (lclTocEntry *) te->formatData; */
_EndDataCompressor(AH, te);
-
- tctx->dataLen = _getFilePos(AH, ctx) - tctx->dataPos;
}
/*
lclTocEntry *tctx = (lclTocEntry *) te->formatData;
tctx->dataPos = _getFilePos(AH, ctx);
+ tctx->dataState = K_OFFSET_POS_SET;
_WriteByte(AH, BLK_BLOBS); /* Block type */
WriteInt(AH, te->id); /* For sanity check */
-
}
/*
int blkType;
int found = 0;
- if (tctx->dataPos == 0)
+ if (tctx->dataState == K_OFFSET_NO_DATA)
return;
- if (!ctx->hasSeek || tctx->dataPos < 0)
+ if (!ctx->hasSeek || tctx->dataState == K_OFFSET_POS_NOT_SET)
{
-
/* Skip over unnecessary blocks until we get the one we want. */
found = 0;
while (id != te->id)
{
-
if ((TocIDRequired(AH, id, ropt) & 2) != 0)
die_horribly(AH, modulename,
"Dumping a specific TOC data block out of order is not supported"
switch (blkType)
{
-
case BLK_DATA:
-
_skipData(AH);
break;
case BLK_BLOBS:
-
_skipBlobs(AH);
break;
default: /* Always have a default */
-
die_horribly(AH, modulename,
"unrecognized data block type (%d) while searching archive\n",
blkType);
break;
}
-
_readBlockHeader(AH, &blkType, &id);
-
}
-
}
else
{
-
/* Grab it */
-
if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
die_horribly(AH, modulename, "error during file seek: %s\n", strerror(errno));
_readBlockHeader(AH, &blkType, &id);
-
}
/* Are we sane? */
switch (blkType)
{
-
case BLK_DATA:
-
_PrintData(AH);
break;
case BLK_BLOBS:
-
if (!AH->connection)
die_horribly(AH, modulename, "large objects cannot be loaded without a database connection\n");
break;
default: /* Always have a default */
-
die_horribly(AH, modulename, "unrecognized data block type %d while restoring archive\n",
blkType);
break;
if (AH->compression != 0)
{
-
while (zp->avail_in != 0)
{
zp->next_out = out;
#ifdef HAVE_LIBZ
}
#endif
-
blkLen = ReadInt(AH);
-
}
#ifdef HAVE_LIBZ
die_horribly(AH, modulename, "could not close compression library: %s\n", zp->msg);
}
#endif
-
}
static void
}
EndRestoreBlobs(AH);
-
}
/*
blkLen = ReadInt(AH);
}
-
}
/*
pos = ftello(AH->FH);
if (pos != ctx->filePos)
{
- write_msg(modulename, "WARNING: ftell mismatch with expected position -- ftell ignored\n");
- pos = ctx->filePos;
+ write_msg(modulename, "WARNING: ftell mismatch with expected position -- ftell used\n");
+ /*
+ * Prior to 1.7 (pg7.3) we relied on the internally maintained pointer.
+ * Now we rely on off_t always.
+ * pos = ctx->filePos;
+ */
}
}
else
res = Z_STREAM_END;
#endif
}
-
-
}
#ifdef HAVE_LIBZ
#else
return 1;
#endif
-
}
/*
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.42 2002/10/16 05:46:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.43 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* Autocommit could be off. We turn it off later but we have to check
* the database version first.
*/
-
+
res = PQexec(conn, "BEGIN;SELECT version();");
if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK ||
die_horribly(AH, modulename, "could not reconnect to database: %s",
PQerrorMessage(newConn));
}
-
} while (need_pass);
if (password)
{
case SQL_SCAN: /* Default state == 0, set in _allocAH */
-
if (qry[pos] == ';' && AH->sqlparse.braceDepth == 0)
{
/* Send It & reset the buffer */
AH->sqlparse.lastChar = qry[pos];
}
-
break;
case SQL_IN_SQL_COMMENT:
-
if (qry[pos] == '\n')
AH->sqlparse.state = SQL_SCAN;
break;
case SQL_IN_EXT_COMMENT:
-
if (AH->sqlparse.lastChar == '*' && qry[pos] == '/')
AH->sqlparse.state = SQL_SCAN;
break;
case SQL_IN_QUOTE:
-
if (!AH->sqlparse.backSlash && AH->sqlparse.quoteChar == qry[pos])
{
/* fprintf(stderr,"[endquote]\n"); */
* stmt
*/
return eos;
-
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_files.c,v 1.19 2002/09/10 18:25:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_files.c,v 1.20 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
if (fclose(AH->FH) != 0)
die_horribly(AH, modulename, "could not close TOC file: %s\n", strerror(errno));
}
-
}
/*
if (tctx->FH == NULL)
die_horribly(AH, modulename, "could not open data file for output\n");
-
}
static size_t
if (GZCLOSE(AH->FH) != 0)
die_horribly(AH, modulename, "could not close data file after reading\n");
-
}
if (ctx->blobToc == NULL)
die_horribly(AH, modulename,
"could not open large object TOC for output: %s\n", strerror(errno));
-
}
/*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.30 2002/09/10 18:22:20 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.31 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
ReadToc(AH);
tarClose(AH, ctx->FH); /* Nothing else in the file... */
}
-
}
/*
/* tm->zFH = gzdopen(dup(fileno(ctx->tarFH)), "rb"); */
#else
-
tm->nFH = ctx->tarFH;
#endif
th = tarOpen(AH, NULL, 'r');
}
-
EndRestoreBlobs(AH);
-
}
die_horribly(AH, modulename,
"could not write null block at end of tar archive\n");
}
-
}
AH->FH = NULL;
sprintf(fname, "blobs.toc");
ctx->blobToc = tarOpen(AH, fname, 'w');
-
}
/*
tarPrintf(AH, ctx->blobToc, "%u %s\n", oid, fname);
tctx->TH = tarOpen(AH, fname, 'w');
-
}
/*
/* WriteInt(AH, 0); */
tarClose(AH, ctx->blobToc);
-
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.304 2002/10/18 22:05:35 petere Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.305 2002/10/22 19:15:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
break;
case 'C': /* Create DB */
-
outputCreate = 1;
break;
oids = true;
break;
-
case 'O': /* Don't reconnect to match owner */
outputNoOwner = 1;
break;
}
archprintf(fout, ");\n");
}
-
} while (PQntuples(res) > 0);
archprintf(fout, "\n\n");