📄 pg_backup_custom.c
字号:
_PrintData(ArchiveHandle *AH){ lclContext *ctx = (lclContext *) AH->formatData; z_streamp zp = ctx->zp; size_t blkLen; char *in = ctx->zlibIn; size_t cnt;#ifdef HAVE_LIBZ int res; char *out = ctx->zlibOut;#endif#ifdef HAVE_LIBZ res = Z_OK; if (AH->compression != 0) { zp->zalloc = Z_NULL; zp->zfree = Z_NULL; zp->opaque = Z_NULL; if (inflateInit(zp) != Z_OK) die_horribly(AH, modulename, "could not initialize compression library: %s\n", zp->msg); }#endif blkLen = ReadInt(AH); while (blkLen != 0) { if (blkLen + 1 > ctx->inSize) { free(ctx->zlibIn); ctx->zlibIn = NULL; ctx->zlibIn = (char *) malloc(blkLen + 1); if (!ctx->zlibIn) die_horribly(AH, modulename, "out of memory\n"); ctx->inSize = blkLen + 1; in = ctx->zlibIn; } cnt = fread(in, 1, blkLen, AH->FH); if (cnt != blkLen) die_horribly(AH, modulename, "could not read data block -- expected %lu, got %lu\n", (unsigned long) blkLen, (unsigned long) cnt); ctx->filePos += blkLen; zp->next_in = in; zp->avail_in = blkLen;#ifdef HAVE_LIBZ if (AH->compression != 0) { while (zp->avail_in != 0) { zp->next_out = out; zp->avail_out = zlibOutSize; res = inflate(zp, 0); if (res != Z_OK && res != Z_STREAM_END) die_horribly(AH, modulename, "could not uncompress data: %s\n", zp->msg); out[zlibOutSize - zp->avail_out] = '\0'; ahwrite(out, 1, zlibOutSize - zp->avail_out, AH); } } else {#endif in[zp->avail_in] = '\0'; ahwrite(in, 1, zp->avail_in, AH); zp->avail_in = 0;#ifdef HAVE_LIBZ }#endif blkLen = ReadInt(AH); }#ifdef HAVE_LIBZ if (AH->compression != 0) { zp->next_in = NULL; zp->avail_in = 0; while (res != Z_STREAM_END) { zp->next_out = out; zp->avail_out = zlibOutSize; res = inflate(zp, 0); if (res != Z_OK && res != Z_STREAM_END) die_horribly(AH, modulename, "could not uncompress data: %s\n", zp->msg); out[zlibOutSize - zp->avail_out] = '\0'; ahwrite(out, 1, zlibOutSize - zp->avail_out, AH); } if (inflateEnd(zp) != Z_OK) die_horribly(AH, modulename, "could not close compression library: %s\n", zp->msg); }#endif}static void_LoadBlobs(ArchiveHandle *AH){ Oid oid; StartRestoreBlobs(AH); oid = ReadInt(AH); while (oid != 0) { StartRestoreBlob(AH, oid); _PrintData(AH); EndRestoreBlob(AH, oid); oid = ReadInt(AH); } EndRestoreBlobs(AH);}/* * Skip the BLOBs from the current file position. * BLOBS are written sequentially as data blocks (see below). * Each BLOB is preceded by it's original OID. * A zero OID indicated the end of the BLOBS */static void_skipBlobs(ArchiveHandle *AH){ Oid oid; oid = ReadInt(AH); while (oid != 0) { _skipData(AH); oid = ReadInt(AH); }}/* * Skip data from current file position. * Data blocks are formatted as an integer length, followed by data. * A zero length denoted the end of the block.*/static void_skipData(ArchiveHandle *AH){ lclContext *ctx = (lclContext *) AH->formatData; size_t blkLen; char *in = ctx->zlibIn; size_t cnt; blkLen = ReadInt(AH); while (blkLen != 0) { if (blkLen > ctx->inSize) { free(ctx->zlibIn); ctx->zlibIn = (char *) malloc(blkLen); ctx->inSize = blkLen; in = ctx->zlibIn; } cnt = fread(in, 1, blkLen, AH->FH); if (cnt != blkLen) die_horribly(AH, modulename, "could not read data block -- expected %lu, got %lu\n", (unsigned long) blkLen, (unsigned long) cnt); ctx->filePos += blkLen; blkLen = ReadInt(AH); }}/* * Write a byte of data to the archive. * * Mandatory. * * Called by the archiver to do integer & byte output to the archive. * These routines are only used to read & write headers & TOC. * */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; else die_horribly(AH, modulename, "could not write byte: %s\n", strerror(errno)); return res;}/* * Read a byte of data from the archive. * * Mandatory * * Called by the archiver to read bytes & integers from the archive. * These routines are only used to read & write headers & TOC. * */static int_ReadByte(ArchiveHandle *AH){ lclContext *ctx = (lclContext *) AH->formatData; int res; res = fgetc(AH->FH); if (res != EOF) ctx->filePos += 1; return res;}/* * Write a buffer of data to the archive. * * Mandatory. * * Called by the archiver to write a block of bytes to the archive. * These routines are only used to read & write headers & TOC. * */static size_t_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len){ lclContext *ctx = (lclContext *) AH->formatData; size_t res; res = fwrite(buf, 1, len, AH->FH); if (res != len) die_horribly(AH, modulename, "write error in _WriteBuf (%lu != %lu)\n", (unsigned long) res, (unsigned long) len); ctx->filePos += res; return res;}/* * Read a block of bytes from the archive. * * Mandatory. * * Called by the archiver to read a block of bytes from the archive * These routines are only used to read & write headers & TOC. * */static size_t_ReadBuf(ArchiveHandle *AH, void *buf, size_t len){ lclContext *ctx = (lclContext *) AH->formatData; size_t res; res = fread(buf, 1, len, AH->FH); ctx->filePos += res; return res;}/* * Close the archive. * * Mandatory. * * When writing the archive, this is the routine that actually starts * the process of saving it to files. No data should be written prior * to this point, since the user could sort the TOC after creating it. * * If an archive is to be written, this toutine must call: * WriteHead to save the archive header * WriteToc to save the TOC entries * WriteDataChunks to save all DATA & BLOBs. * */static void_CloseArchive(ArchiveHandle *AH){ lclContext *ctx = (lclContext *) AH->formatData; off_t tpos; if (AH->mode == archModeWrite) { WriteHead(AH); tpos = ftello(AH->FH); WriteToc(AH); ctx->dataStart = _getFilePos(AH, ctx); WriteDataChunks(AH); /* * This is not an essential operation - it is really only needed * if we expect to be doing seeks to read the data back - it may * be ok to just use the existing self-consistent block * formatting. */ if (ctx->hasSeek) { fseeko(AH->FH, tpos, SEEK_SET); WriteToc(AH); } } if (fclose(AH->FH) != 0) die_horribly(AH, modulename, "could not close archive file: %s\n", strerror(errno)); AH->FH = NULL;}/*-------------------------------------------------- * END OF FORMAT CALLBACKS *-------------------------------------------------- *//* * Get the current position in the archive file. */static off_t_getFilePos(ArchiveHandle *AH, lclContext *ctx){ off_t pos; if (ctx->hasSeek) { pos = ftello(AH->FH); if (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 pos = ctx->filePos; return pos;}/* * Read a data block header. The format changed in V1.3, so we * put the code here for simplicity. */static void_readBlockHeader(ArchiveHandle *AH, int *type, int *id){ if (AH->version < K_VERS_1_3) *type = BLK_DATA; else *type = _ReadByte(AH);; *id = ReadInt(AH);}/* * If zlib is available, then startit up. This is called from * StartData & StartBlob. The buffers are setup in the Init routine. * */static void_StartDataCompressor(ArchiveHandle *AH, TocEntry *te){ lclContext *ctx = (lclContext *) AH->formatData; z_streamp zp = ctx->zp;#ifdef HAVE_LIBZ if (AH->compression < 0 || AH->compression > 9) AH->compression = Z_DEFAULT_COMPRESSION; if (AH->compression != 0) { zp->zalloc = Z_NULL; zp->zfree = Z_NULL; zp->opaque = Z_NULL; if (deflateInit(zp, AH->compression) != Z_OK) die_horribly(AH, modulename, "could not initialize compression library: %s\n", zp->msg); }#else AH->compression = 0;#endif /* Just be paranoid - maybe End is called after Start, with no Write */ zp->next_out = ctx->zlibOut; zp->avail_out = zlibOutSize;}/* * Send compressed data to the output stream (via ahwrite). * Each data chunk is preceded by it's length. * In the case of Z0, or no zlib, just write the raw data. * */static int_DoDeflate(ArchiveHandle *AH, lclContext *ctx, int flush){ z_streamp zp = ctx->zp;#ifdef HAVE_LIBZ char *out = ctx->zlibOut; int res = Z_OK; if (AH->compression != 0) { res = deflate(zp, flush); if (res == Z_STREAM_ERROR) die_horribly(AH, modulename, "could not compress data: %s\n", zp->msg); if (((flush == Z_FINISH) && (zp->avail_out < zlibOutSize)) || (zp->avail_out == 0) || (zp->avail_in != 0) ) { /* * Extra paranoia: avoid zero-length chunks since a zero * length chunk is the EOF marker. This should never happen * but... */ if (zp->avail_out < zlibOutSize) { /* * printf("Wrote %lu byte deflated chunk\n", (unsigned * long) (zlibOutSize - zp->avail_out)); */ WriteInt(AH, zlibOutSize - zp->avail_out); if (fwrite(out, 1, zlibOutSize - zp->avail_out, AH->FH) != (zlibOutSize - zp->avail_out)) die_horribly(AH, modulename, "could not write compressed chunk\n"); ctx->filePos += zlibOutSize - zp->avail_out; } zp->next_out = out; zp->avail_out = zlibOutSize; } } else#endif { if (zp->avail_in > 0) { WriteInt(AH, zp->avail_in); if (fwrite(zp->next_in, 1, zp->avail_in, AH->FH) != zp->avail_in) die_horribly(AH, modulename, "could not write uncompressed chunk\n"); ctx->filePos += zp->avail_in; zp->avail_in = 0; } else {#ifdef HAVE_LIBZ if (flush == Z_FINISH) res = Z_STREAM_END;#endif } }#ifdef HAVE_LIBZ return res;#else return 1;#endif}/* * Terminate zlib context and flush it's buffers. If no zlib * then just return. * */static void_EndDataCompressor(ArchiveHandle *AH, TocEntry *te){#ifdef HAVE_LIBZ lclContext *ctx = (lclContext *) AH->formatData; z_streamp zp = ctx->zp; int res; if (AH->compression != 0) { zp->next_in = NULL; zp->avail_in = 0; do { /* printf("Ending data output\n"); */ res = _DoDeflate(AH, ctx, Z_FINISH); } while (res != Z_STREAM_END); if (deflateEnd(zp) != Z_OK) die_horribly(AH, modulename, "could not close compression stream: %s\n", zp->msg); }#endif /* Send the end marker */ WriteInt(AH, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -