summaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_backup_files.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2000-07-04 14:25:28 +0000
committerBruce Momjian <bruce@momjian.us>2000-07-04 14:25:28 +0000
commit500b62b0570f29c708083a8f64988329bfaec5d5 (patch)
tree6216e7853c58c1b80e9011d149af53f435181553 /src/bin/pg_dump/pg_backup_files.c
parent20c01ef1305ef20207c0904656b776a31501000a (diff)
pg_dump patch from Philip Warner
Diffstat (limited to 'src/bin/pg_dump/pg_backup_files.c')
-rw-r--r--src/bin/pg_dump/pg_backup_files.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/bin/pg_dump/pg_backup_files.c b/src/bin/pg_dump/pg_backup_files.c
new file mode 100644
index 00000000000..bbf30de9aaa
--- /dev/null
+++ b/src/bin/pg_dump/pg_backup_files.c
@@ -0,0 +1,303 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_backup_files.c
+ *
+ * This file is copied from the 'custom' format file, but dumps data into
+ * separate files, and the TOC into the 'main' file.
+ *
+ * IT IS FOR DEMONSTRATION PURPOSES ONLY.
+ *
+ * (and could probably be used as a basis for writing a tar file)
+ *
+ * See the headers to pg_restore for more details.
+ *
+ * Copyright (c) 2000, Philip Warner
+ * Rights are granted to use this software in any way so long
+ * as this notice is not removed.
+ *
+ * The author is not responsible for loss or damages that may
+ * result from it's use.
+ *
+ *
+ * IDENTIFICATION
+ *
+ * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
+ *
+ * Initial version.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "pg_backup.h"
+#include "pg_backup_archiver.h"
+
+static void _ArchiveEntry(ArchiveHandle* AH, TocEntry* te);
+static void _StartData(ArchiveHandle* AH, TocEntry* te);
+static int _WriteData(ArchiveHandle* AH, const void* data, int dLen);
+static void _EndData(ArchiveHandle* AH, TocEntry* te);
+static int _WriteByte(ArchiveHandle* AH, const int i);
+static int _ReadByte(ArchiveHandle* );
+static int _WriteBuf(ArchiveHandle* AH, const void* buf, int len);
+static int _ReadBuf(ArchiveHandle* AH, void* buf, int len);
+static void _CloseArchive(ArchiveHandle* AH);
+static void _PrintTocData(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt);
+static void _WriteExtraToc(ArchiveHandle* AH, TocEntry* te);
+static void _ReadExtraToc(ArchiveHandle* AH, TocEntry* te);
+static void _PrintExtraToc(ArchiveHandle* AH, TocEntry* te);
+
+
+typedef struct {
+ int hasSeek;
+ int filePos;
+} lclContext;
+
+typedef struct {
+#ifdef HAVE_ZLIB
+ gzFile *FH;
+#else
+ FILE *FH;
+#endif
+ char *filename;
+} lclTocEntry;
+
+/*
+ * Initializer
+ */
+void InitArchiveFmt_Files(ArchiveHandle* AH)
+{
+ lclContext* ctx;
+
+ /* Assuming static functions, this can be copied for each format. */
+ AH->ArchiveEntryPtr = _ArchiveEntry;
+ AH->StartDataPtr = _StartData;
+ AH->WriteDataPtr = _WriteData;
+ AH->EndDataPtr = _EndData;
+ AH->WriteBytePtr = _WriteByte;
+ AH->ReadBytePtr = _ReadByte;
+ AH->WriteBufPtr = _WriteBuf;
+ AH->ReadBufPtr = _ReadBuf;
+ AH->ClosePtr = _CloseArchive;
+ AH->PrintTocDataPtr = _PrintTocData;
+ AH->ReadExtraTocPtr = _ReadExtraToc;
+ AH->WriteExtraTocPtr = _WriteExtraToc;
+ AH->PrintExtraTocPtr = _PrintExtraToc;
+
+ /*
+ * Set up some special context used in compressing data.
+ */
+ ctx = (lclContext*)malloc(sizeof(lclContext));
+ AH->formatData = (void*)ctx;
+ ctx->filePos = 0;
+
+ /*
+ * Now open the TOC file
+ */
+ if (AH->mode == archModeWrite) {
+ if (AH->fSpec && strcmp(AH->fSpec,"") != 0) {
+ AH->FH = fopen(AH->fSpec, PG_BINARY_W);
+ } else {
+ AH->FH = stdout;
+ }
+ ctx->hasSeek = (fseek(AH->FH, 0, SEEK_CUR) == 0);
+
+ if (AH->compression < 0 || AH->compression > 9) {
+ AH->compression = Z_DEFAULT_COMPRESSION;
+ }
+
+
+ } else {
+ if (AH->fSpec && strcmp(AH->fSpec,"") != 0) {
+ AH->FH = fopen(AH->fSpec, PG_BINARY_R);
+ } else {
+ AH->FH = stdin;
+ }
+ ctx->hasSeek = (fseek(AH->FH, 0, SEEK_CUR) == 0);
+
+ ReadHead(AH);
+ ReadToc(AH);
+ fclose(AH->FH); /* Nothing else in the file... */
+ }
+
+}
+
+/*
+ * - Start a new TOC entry
+ * Setup the output file name.
+ */
+static void _ArchiveEntry(ArchiveHandle* AH, TocEntry* te)
+{
+ lclTocEntry* ctx;
+ char fn[1024];
+
+ ctx = (lclTocEntry*)malloc(sizeof(lclTocEntry));
+ if (te->dataDumper) {
+#ifdef HAVE_ZLIB
+ if (AH->compression == 0) {
+ sprintf(fn, "%d.dat", te->id);
+ } else {
+ sprintf(fn, "%d.dat.gz", te->id);
+ }
+#else
+ sprintf(fn, "%d.dat", te->id);
+#endif
+ ctx->filename = strdup(fn);
+ } else {
+ ctx->filename = NULL;
+ ctx->FH = NULL;
+ }
+ te->formatData = (void*)ctx;
+}
+
+static void _WriteExtraToc(ArchiveHandle* AH, TocEntry* te)
+{
+ lclTocEntry* ctx = (lclTocEntry*)te->formatData;
+
+ if (ctx->filename) {
+ WriteStr(AH, ctx->filename);
+ } else {
+ WriteStr(AH, "");
+ }
+}
+
+static void _ReadExtraToc(ArchiveHandle* AH, TocEntry* te)
+{
+ lclTocEntry* ctx = (lclTocEntry*)te->formatData;
+
+ if (ctx == NULL) {
+ ctx = (lclTocEntry*)malloc(sizeof(lclTocEntry));
+ te->formatData = (void*)ctx;
+ }
+
+ ctx->filename = ReadStr(AH);
+ if (strlen(ctx->filename) == 0) {
+ free(ctx->filename);
+ ctx->filename = NULL;
+ }
+ ctx->FH = NULL;
+}
+
+static void _PrintExtraToc(ArchiveHandle* AH, TocEntry* te)
+{
+ lclTocEntry* ctx = (lclTocEntry*)te->formatData;
+
+ ahprintf(AH, "-- File: %s\n", ctx->filename);
+}
+
+static void _StartData(ArchiveHandle* AH, TocEntry* te)
+{
+ lclTocEntry* tctx = (lclTocEntry*)te->formatData;
+ char fmode[10];
+
+ sprintf(fmode, "wb%d", AH->compression);
+
+#ifdef HAVE_ZLIB
+ tctx->FH = gzopen(tctx->filename, fmode);
+#else
+ tctx->FH = fopen(tctx->filename, PG_BINARY_W);
+#endif
+}
+
+static int _WriteData(ArchiveHandle* AH, const void* data, int dLen)
+{
+ lclTocEntry* tctx = (lclTocEntry*)AH->currToc->formatData;
+
+ GZWRITE((void*)data, 1, dLen, tctx->FH);
+
+ return dLen;
+}
+
+static void _EndData(ArchiveHandle* AH, TocEntry* te)
+{
+ lclTocEntry* tctx = (lclTocEntry*) te->formatData;
+
+ /* Close the file */
+ GZCLOSE(tctx->FH);
+ tctx->FH = NULL;
+}
+
+/*
+ * Print data for a given TOC entry
+*/
+static void _PrintTocData(ArchiveHandle* AH, TocEntry* te, RestoreOptions *ropt)
+{
+ lclTocEntry* tctx = (lclTocEntry*) te->formatData;
+ char buf[4096];
+ int cnt;
+
+ if (!tctx->filename)
+ return;
+
+#ifdef HAVE_ZLIB
+ AH->FH = gzopen(tctx->filename,"rb");
+#else
+ AH->FH = fopen(tctx->filename,PG_BINARY_R);
+#endif
+
+ ahprintf(AH, "--\n-- Data for TOC Entry ID %d (OID %s) %s %s\n--\n\n",
+ te->id, te->oid, te->desc, te->name);
+
+ while ( (cnt = GZREAD(buf, 1, 4096, AH->FH)) > 0) {
+ ahwrite(buf, 1, cnt, AH);
+ }
+
+ GZCLOSE(AH->FH);
+
+ ahprintf(AH, "\n\n");
+}
+
+static int _WriteByte(ArchiveHandle* AH, const int i)
+{
+ lclContext* ctx = (lclContext*)AH->formatData;
+ int res;
+
+ res = fputc(i, AH->FH);
+ if (res != EOF) {
+ ctx->filePos += 1;
+ }
+ return res;
+}
+
+static int _ReadByte(ArchiveHandle* AH)
+{
+ lclContext* ctx = (lclContext*)AH->formatData;
+ int res;
+
+ res = fgetc(AH->FH);
+ if (res != EOF) {
+ ctx->filePos += 1;
+ }
+ return res;
+}
+
+static int _WriteBuf(ArchiveHandle* AH, const void* buf, int len)
+{
+ lclContext* ctx = (lclContext*)AH->formatData;
+ int res;
+ res = fwrite(buf, 1, len, AH->FH);
+ ctx->filePos += res;
+ return res;
+}
+
+static int _ReadBuf(ArchiveHandle* AH, void* buf, int len)
+{
+ lclContext* ctx = (lclContext*)AH->formatData;
+ int res;
+ res = fread(buf, 1, len, AH->FH);
+ ctx->filePos += res;
+ return res;
+}
+
+static void _CloseArchive(ArchiveHandle* AH)
+{
+ if (AH->mode == archModeWrite) {
+ WriteHead(AH);
+ WriteToc(AH);
+ fclose(AH->FH);
+ WriteDataChunks(AH);
+ }
+
+ AH->FH = NULL;
+}
+