PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_backup_tar.c File Reference
#include "postgres_fe.h"
#include <sys/stat.h>
#include <ctype.h>
#include <limits.h>
#include <unistd.h>
#include "common/file_utils.h"
#include "fe_utils/string_utils.h"
#include "pg_backup_archiver.h"
#include "pg_backup_tar.h"
#include "pg_backup_utils.h"
#include "pgtar.h"
Include dependency graph for pg_backup_tar.c:

Go to the source code of this file.

Data Structures

struct  TAR_MEMBER
 
struct  lclContext
 
struct  lclTocEntry
 

Macros

#define K_STD_BUF_SIZE   1024
 

Functions

static void _ArchiveEntry (ArchiveHandle *AH, TocEntry *te)
 
static void _StartData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteData (ArchiveHandle *AH, const void *data, size_t dLen)
 
static void _EndData (ArchiveHandle *AH, TocEntry *te)
 
static int _WriteByte (ArchiveHandle *AH, const int i)
 
static int _ReadByte (ArchiveHandle *AH)
 
static void _WriteBuf (ArchiveHandle *AH, const void *buf, size_t len)
 
static void _ReadBuf (ArchiveHandle *AH, void *buf, size_t len)
 
static void _CloseArchive (ArchiveHandle *AH)
 
static void _PrintTocData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _ReadExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _PrintExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _StartLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadLOs (ArchiveHandle *AH, TocEntry *te)
 
static TAR_MEMBERtarOpen (ArchiveHandle *AH, const char *filename, char mode)
 
static void tarClose (ArchiveHandle *AH, TAR_MEMBER *th)
 
static int tarPrintf (TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(2
 
static int static void _tarAddFile (ArchiveHandle *AH, TAR_MEMBER *th)
 
static TAR_MEMBER_tarPositionTo (ArchiveHandle *AH, const char *filename)
 
static size_t tarRead (void *buf, size_t len, TAR_MEMBER *th)
 
static size_t tarWrite (const void *buf, size_t len, TAR_MEMBER *th)
 
static void _tarWriteHeader (TAR_MEMBER *th)
 
static int _tarGetHeader (ArchiveHandle *AH, TAR_MEMBER *th)
 
static size_t _tarReadRaw (ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
 
static size_t _scriptOut (ArchiveHandle *AH, const void *buf, size_t len)
 
void InitArchiveFmt_Tar (ArchiveHandle *AH)
 
static void _PrintFileData (ArchiveHandle *AH, char *filename)
 
bool isValidTarHeader (char *header)
 

Macro Definition Documentation

◆ K_STD_BUF_SIZE

#define K_STD_BUF_SIZE   1024

Definition at line 63 of file pg_backup_tar.c.

Function Documentation

◆ _ArchiveEntry()

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 234 of file pg_backup_tar.c.

235{
236 lclTocEntry *ctx;
237 char fn[K_STD_BUF_SIZE];
238
240 if (te->dataDumper != NULL)
241 {
242 snprintf(fn, sizeof(fn), "%d.dat", te->dumpId);
243 ctx->filename = pg_strdup(fn);
244 }
245 else
246 {
247 ctx->filename = NULL;
248 ctx->TH = NULL;
249 }
250 te->formatData = ctx;
251}
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define pg_malloc0_object(type)
Definition: fe_memutils.h:51
#define K_STD_BUF_SIZE
Definition: pg_backup_tar.c:63
#define snprintf
Definition: port.h:238
DataDumperPtr dataDumper
TAR_MEMBER * TH
Definition: pg_backup_tar.c:93
static void * fn(void *arg)
Definition: thread-alloc.c:119

References _tocEntry::dataDumper, _tocEntry::dumpId, lclTocEntry::filename, fn(), _tocEntry::formatData, K_STD_BUF_SIZE, pg_malloc0_object, pg_strdup(), snprintf, and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

◆ _CloseArchive()

static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 769 of file pg_backup_tar.c.

770{
771 lclContext *ctx = (lclContext *) AH->formatData;
772 TAR_MEMBER *th;
773 RestoreOptions *ropt;
774 RestoreOptions *savRopt;
775 DumpOptions *savDopt;
776 int savVerbose,
777 i;
778
779 if (AH->mode == archModeWrite)
780 {
781 /*
782 * Write the Header & TOC to the archive FIRST
783 */
784 th = tarOpen(AH, "toc.dat", 'w');
785 ctx->FH = th;
786 WriteHead(AH);
787 WriteToc(AH);
788 tarClose(AH, th); /* Not needed any more */
789
790 /*
791 * Now send the data (tables & LOs)
792 */
793 WriteDataChunks(AH, NULL);
794
795 /*
796 * Now this format wants to append a script which does a full restore
797 * if the files have been extracted.
798 */
799 th = tarOpen(AH, "restore.sql", 'w');
800
801 tarPrintf(th, "--\n"
802 "-- NOTE:\n"
803 "--\n"
804 "-- File paths need to be edited. Search for $$PATH$$ and\n"
805 "-- replace it with the path to the directory containing\n"
806 "-- the extracted data files.\n"
807 "--\n");
808
810
811 ctx->isSpecialScript = 1;
812 ctx->scriptTH = th;
813
814 ropt = NewRestoreOptions();
815 memcpy(ropt, AH->public.ropt, sizeof(RestoreOptions));
816 ropt->filename = NULL;
817 ropt->dropSchema = 1;
818 ropt->superuser = NULL;
819 ropt->suppressDumpWarnings = true;
820
821 savDopt = AH->public.dopt;
822 savRopt = AH->public.ropt;
823
824 SetArchiveOptions((Archive *) AH, NULL, ropt);
825
826 savVerbose = AH->public.verbose;
827 AH->public.verbose = 0;
828
829 RestoreArchive((Archive *) AH);
830
831 SetArchiveOptions((Archive *) AH, savDopt, savRopt);
832
833 AH->public.verbose = savVerbose;
834
835 tarClose(AH, th);
836
837 ctx->isSpecialScript = 0;
838
839 /*
840 * EOF marker for tar files is two blocks of NULLs.
841 */
842 for (i = 0; i < TAR_BLOCK_SIZE * 2; i++)
843 {
844 if (fputc(0, ctx->tarFH) == EOF)
846 }
847
848 /* Sync the output file if one is defined */
849 if (AH->dosync && AH->fSpec)
850 (void) fsync_fname(AH->fSpec, false);
851 }
852
853 AH->FH = NULL;
854}
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:755
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
RestoreOptions * NewRestoreOptions(void)
@ archModeWrite
Definition: pg_backup.h:51
void SetArchiveOptions(Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
void RestoreArchive(Archive *AHX)
void WriteHead(ArchiveHandle *AH)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void WriteToc(ArchiveHandle *AH)
#define WRITE_ERROR_EXIT
static int tarPrintf(TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(2
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
static size_t _scriptOut(ArchiveHandle *AH, const void *buf, size_t len)
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *th)
#define TAR_BLOCK_SIZE
Definition: pgtar.h:17
DumpOptions * dopt
Definition: pg_backup.h:219
int verbose
Definition: pg_backup.h:222
RestoreOptions * ropt
Definition: pg_backup.h:220
CustomOutPtrType CustomOutPtr
FILE * tarFH
Definition: pg_backup_tar.c:83
TAR_MEMBER * FH
Definition: pg_backup_tar.c:86
TAR_MEMBER * scriptTH
Definition: pg_backup_tar.c:88
int isSpecialScript
Definition: pg_backup_tar.c:87

References _scriptOut(), archModeWrite, _archiveHandle::CustomOutPtr, Archive::dopt, _archiveHandle::FH, lclContext::FH, _archiveHandle::formatData, fsync_fname(), i, if(), lclContext::isSpecialScript, _archiveHandle::mode, NewRestoreOptions(), _archiveHandle::public, RestoreArchive(), Archive::ropt, lclContext::scriptTH, SetArchiveOptions(), TAR_BLOCK_SIZE, tarClose(), lclContext::tarFH, tarOpen(), tarPrintf(), Archive::verbose, WRITE_ERROR_EXIT, WriteDataChunks(), WriteHead(), and WriteToc().

Referenced by InitArchiveFmt_Tar().

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 549 of file pg_backup_tar.c.

550{
551 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
552
553 /* Close the file */
554 tarClose(AH, tctx->TH);
555 tctx->TH = NULL;
556}

References _tocEntry::formatData, tarClose(), and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

◆ _EndLO()

static void _EndLO ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 922 of file pg_backup_tar.c.

923{
924 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
925
926 tarClose(AH, tctx->TH);
927}

References _tocEntry::formatData, tarClose(), and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

◆ _EndLOs()

static void _EndLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 936 of file pg_backup_tar.c.

937{
938 lclContext *ctx = (lclContext *) AH->formatData;
939
940 /* Write out a fake zero OID to mark end-of-LOs. */
941 /* WriteInt(AH, 0); */
942
943 tarClose(AH, ctx->loToc);
944}
TAR_MEMBER * loToc
Definition: pg_backup_tar.c:82

References _archiveHandle::formatData, lclContext::loToc, and tarClose().

Referenced by InitArchiveFmt_Tar().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 643 of file pg_backup_tar.c.

644{
645 Oid oid;
646 lclContext *ctx = (lclContext *) AH->formatData;
647 TAR_MEMBER *th;
648 size_t cnt;
649 bool foundLO = false;
650 char buf[4096];
651
652 StartRestoreLOs(AH);
653
654 /*
655 * The blobs_NNN.toc or blobs.toc file is fairly useless to us because it
656 * will appear only after the associated blob_NNN.dat files. For archive
657 * versions >= 16 we can look at the BLOBS entry's te->tag to discover the
658 * OID of the first blob we want to restore, and then search forward to
659 * find the appropriate blob_<oid>.dat file. For older versions we rely
660 * on the knowledge that there was only one BLOBS entry and just search
661 * for the first blob_<oid>.dat file. Once we find the first blob file to
662 * restore, restore all blobs until we reach the blobs[_NNN].toc file.
663 */
664 if (AH->version >= K_VERS_1_16)
665 {
666 /* We rely on atooid to not complain about nnnn..nnnn tags */
667 oid = atooid(te->tag);
668 snprintf(buf, sizeof(buf), "blob_%u.dat", oid);
669 th = tarOpen(AH, buf, 'r'); /* Advance to first desired file */
670 }
671 else
672 th = tarOpen(AH, NULL, 'r'); /* Open next file */
673
674 while (th != NULL)
675 {
676 ctx->FH = th;
677
678 if (strncmp(th->targetFile, "blob_", 5) == 0)
679 {
680 oid = atooid(&th->targetFile[5]);
681 if (oid != 0)
682 {
683 pg_log_info("restoring large object with OID %u", oid);
684
685 StartRestoreLO(AH, oid, AH->public.ropt->dropSchema);
686
687 while ((cnt = tarRead(buf, 4095, th)) > 0)
688 {
689 buf[cnt] = '\0';
690 ahwrite(buf, 1, cnt, AH);
691 }
692 EndRestoreLO(AH, oid);
693 foundLO = true;
694 }
695 tarClose(AH, th);
696 }
697 else
698 {
699 tarClose(AH, th);
700
701 /*
702 * Once we have found the first LO, stop at the first non-LO entry
703 * (which will be 'blobs[_NNN].toc'). This coding would eat all
704 * the rest of the archive if there are no LOs ... but this
705 * function shouldn't be called at all in that case.
706 */
707 if (foundLO)
708 break;
709 }
710
711 th = tarOpen(AH, NULL, 'r');
712 }
713 EndRestoreLOs(AH);
714}
#define pg_log_info(...)
Definition: logging.h:124
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
void StartRestoreLOs(ArchiveHandle *AH)
void EndRestoreLO(ArchiveHandle *AH, Oid oid)
void EndRestoreLOs(ArchiveHandle *AH)
void StartRestoreLO(ArchiveHandle *AH, Oid oid, bool drop)
#define K_VERS_1_16
static size_t tarRead(void *buf, size_t len, TAR_MEMBER *th)
static char * buf
Definition: pg_test_fsync.c:72
unsigned int Oid
Definition: postgres_ext.h:31
#define atooid(x)
Definition: postgres_ext.h:42

References ahwrite(), atooid, buf, _restoreOptions::dropSchema, EndRestoreLO(), EndRestoreLOs(), lclContext::FH, _archiveHandle::formatData, K_VERS_1_16, pg_log_info, _archiveHandle::public, Archive::ropt, snprintf, StartRestoreLO(), StartRestoreLOs(), _tocEntry::tag, tarClose(), TAR_MEMBER::targetFile, tarOpen(), tarRead(), and _archiveHandle::version.

Referenced by _PrintTocData().

◆ _PrintExtraToc()

static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 285 of file pg_backup_tar.c.

286{
287 lclTocEntry *ctx = (lclTocEntry *) te->formatData;
288
289 if (AH->public.verbose && ctx->filename != NULL)
290 ahprintf(AH, "-- File: %s\n", ctx->filename);
291}
int ahprintf(ArchiveHandle *AH, const char *fmt,...)

References ahprintf(), lclTocEntry::filename, _tocEntry::formatData, if(), _archiveHandle::public, and Archive::verbose.

Referenced by InitArchiveFmt_Tar().

◆ _PrintFileData()

static void _PrintFileData ( ArchiveHandle AH,
char *  filename 
)
static

Definition at line 562 of file pg_backup_tar.c.

563{
564 lclContext *ctx = (lclContext *) AH->formatData;
565 char buf[4096];
566 size_t cnt;
567 TAR_MEMBER *th;
568
569 if (!filename)
570 return;
571
572 th = tarOpen(AH, filename, 'r');
573 ctx->FH = th;
574
575 while ((cnt = tarRead(buf, 4095, th)) > 0)
576 {
577 buf[cnt] = '\0';
578 ahwrite(buf, 1, cnt, AH);
579 }
580
581 tarClose(AH, th);
582}
static char * filename
Definition: pg_dumpall.c:119

References ahwrite(), buf, lclContext::FH, filename, _archiveHandle::formatData, if(), tarClose(), tarOpen(), and tarRead().

Referenced by _PrintTocData().

◆ _PrintTocData()

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 589 of file pg_backup_tar.c.

590{
591 lclContext *ctx = (lclContext *) AH->formatData;
592 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
593 int pos1;
594
595 if (!tctx->filename)
596 return;
597
598 /*
599 * If we're writing the special restore.sql script, emit a suitable
600 * command to include each table's data from the corresponding file.
601 *
602 * In the COPY case this is a bit klugy because the regular COPY command
603 * was already printed before we get control.
604 */
605 if (ctx->isSpecialScript)
606 {
607 if (te->copyStmt)
608 {
609 /* Abort the COPY FROM stdin */
610 ahprintf(AH, "\\.\n");
611
612 /*
613 * The COPY statement should look like "COPY ... FROM stdin;\n",
614 * see dumpTableData().
615 */
616 pos1 = (int) strlen(te->copyStmt) - 13;
617 if (pos1 < 6 || strncmp(te->copyStmt, "COPY ", 5) != 0 ||
618 strcmp(te->copyStmt + pos1, " FROM stdin;\n") != 0)
619 pg_fatal("unexpected COPY statement syntax: \"%s\"",
620 te->copyStmt);
621
622 /* Emit all but the FROM part ... */
623 ahwrite(te->copyStmt, 1, pos1, AH);
624 /* ... and insert modified FROM */
625 ahprintf(AH, " FROM '$$PATH$$/%s';\n\n", tctx->filename);
626 }
627 else
628 {
629 /* --inserts mode, no worries, just include the data file */
630 ahprintf(AH, "\\i $$PATH$$/%s\n\n", tctx->filename);
631 }
632
633 return;
634 }
635
636 if (strcmp(te->desc, "BLOBS") == 0)
637 _LoadLOs(AH, te);
638 else
639 _PrintFileData(AH, tctx->filename);
640}
static void _PrintFileData(ArchiveHandle *AH, char *filename)
static void _LoadLOs(ArchiveHandle *AH, TocEntry *te)
#define pg_fatal(...)

References _LoadLOs(), _PrintFileData(), ahprintf(), ahwrite(), _tocEntry::copyStmt, _tocEntry::desc, _archiveHandle::formatData, _tocEntry::formatData, lclContext::isSpecialScript, and pg_fatal.

Referenced by InitArchiveFmt_Tar().

◆ _ReadBuf()

static void _ReadBuf ( ArchiveHandle AH,
void *  buf,
size_t  len 
)
static

Definition at line 757 of file pg_backup_tar.c.

758{
759 lclContext *ctx = (lclContext *) AH->formatData;
760
761 if (tarRead(buf, len, ctx->FH) != len)
762 /* We already would have exited for errors on reads, must be EOF */
763 pg_fatal("could not read from input file: end of file");
764
765 ctx->filePos += len;
766}
const void size_t len
pgoff_t filePos
Definition: pg_backup_tar.c:81

References buf, lclContext::FH, lclContext::filePos, _archiveHandle::formatData, if(), len, pg_fatal, and tarRead().

Referenced by InitArchiveFmt_Tar().

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 731 of file pg_backup_tar.c.

732{
733 lclContext *ctx = (lclContext *) AH->formatData;
734 size_t res;
735 unsigned char c;
736
737 res = tarRead(&c, 1, ctx->FH);
738 if (res != 1)
739 /* We already would have exited for errors on reads, must be EOF */
740 pg_fatal("could not read from input file: end of file");
741 ctx->filePos += 1;
742 return c;
743}
char * c

References lclContext::FH, lclContext::filePos, _archiveHandle::formatData, pg_fatal, res, and tarRead().

Referenced by InitArchiveFmt_Tar().

◆ _ReadExtraToc()

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 265 of file pg_backup_tar.c.

266{
267 lclTocEntry *ctx = (lclTocEntry *) te->formatData;
268
269 if (ctx == NULL)
270 {
272 te->formatData = ctx;
273 }
274
275 ctx->filename = ReadStr(AH);
276 if (strlen(ctx->filename) == 0)
277 {
278 free(ctx->filename);
279 ctx->filename = NULL;
280 }
281 ctx->TH = NULL;
282}
#define free(a)
Definition: header.h:65
char * ReadStr(ArchiveHandle *AH)

References lclTocEntry::filename, _tocEntry::formatData, free, if(), pg_malloc0_object, ReadStr(), and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

◆ _scriptOut()

static size_t _scriptOut ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 857 of file pg_backup_tar.c.

858{
859 lclContext *ctx = (lclContext *) AH->formatData;
860
861 return tarWrite(buf, len, ctx->scriptTH);
862}
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)

References buf, _archiveHandle::formatData, len, lclContext::scriptTH, and tarWrite().

Referenced by _CloseArchive().

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 294 of file pg_backup_tar.c.

295{
296 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
297
298 tctx->TH = tarOpen(AH, tctx->filename, 'w');
299}

References lclTocEntry::filename, _tocEntry::formatData, tarOpen(), and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

◆ _StartLO()

static void _StartLO ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 896 of file pg_backup_tar.c.

897{
898 lclContext *ctx = (lclContext *) AH->formatData;
899 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
900 char fname[255];
901
902 if (oid == 0)
903 pg_fatal("invalid OID for large object (%u)", oid);
904
906 pg_fatal("compression is not supported by tar archive format");
907
908 sprintf(fname, "blob_%u.dat", oid);
909
910 tarPrintf(ctx->loToc, "%u %s\n", oid, fname);
911
912 tctx->TH = tarOpen(AH, fname, 'w');
913}
@ PG_COMPRESSION_NONE
Definition: compression.h:23
#define sprintf
Definition: port.h:240
pg_compress_specification compression_spec
pg_compress_algorithm algorithm
Definition: compression.h:34

References pg_compress_specification::algorithm, _archiveHandle::compression_spec, _archiveHandle::formatData, _tocEntry::formatData, lclContext::loToc, PG_COMPRESSION_NONE, pg_fatal, sprintf, tarOpen(), and tarPrintf().

Referenced by InitArchiveFmt_Tar().

◆ _StartLOs()

static void _StartLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 879 of file pg_backup_tar.c.

880{
881 lclContext *ctx = (lclContext *) AH->formatData;
882 char fname[K_STD_BUF_SIZE];
883
884 sprintf(fname, "blobs_%d.toc", te->dumpId);
885 ctx->loToc = tarOpen(AH, fname, 'w');
886}

References _tocEntry::dumpId, _archiveHandle::formatData, K_STD_BUF_SIZE, lclContext::loToc, sprintf, and tarOpen().

Referenced by InitArchiveFmt_Tar().

◆ _tarAddFile()

static void _tarAddFile ( ArchiveHandle AH,
TAR_MEMBER th 
)
static

Definition at line 1014 of file pg_backup_tar.c.

1015{
1016 lclContext *ctx = (lclContext *) AH->formatData;
1017 FILE *tmp = th->tmpFH; /* Grab it for convenience */
1018 char buf[32768];
1019 size_t cnt;
1020 pgoff_t len = 0;
1021 size_t res;
1022 size_t i,
1023 pad;
1024
1025 /*
1026 * Find file len & go back to start.
1027 */
1028 if (fseeko(tmp, 0, SEEK_END) != 0)
1029 pg_fatal("error during file seek: %m");
1030 th->fileLen = ftello(tmp);
1031 if (th->fileLen < 0)
1032 pg_fatal("could not determine seek position in archive file: %m");
1033 if (fseeko(tmp, 0, SEEK_SET) != 0)
1034 pg_fatal("error during file seek: %m");
1035
1036 _tarWriteHeader(th);
1037
1038 while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
1039 {
1040 if ((res = fwrite(buf, 1, cnt, th->tarFH)) != cnt)
1042 len += res;
1043 }
1044 if (!feof(tmp))
1045 READ_ERROR_EXIT(tmp);
1046
1047 if (fclose(tmp) != 0) /* This *should* delete it... */
1048 pg_fatal("could not close temporary file: %m");
1049
1050 if (len != th->fileLen)
1051 pg_fatal("actual file length (%lld) does not match expected (%lld)",
1052 (long long) len, (long long) th->fileLen);
1053
1055 for (i = 0; i < pad; i++)
1056 {
1057 if (fputc('\0', th->tarFH) == EOF)
1059 }
1060
1061 ctx->tarFHpos += len + pad;
1062}
#define READ_ERROR_EXIT(fd)
static void _tarWriteHeader(TAR_MEMBER *th)
static size_t tarPaddingBytesRequired(size_t len)
Definition: pgtar.h:79
#define pgoff_t
Definition: port.h:373
pgoff_t fileLen
Definition: pg_backup_tar.c:74
FILE * tarFH
Definition: pg_backup_tar.c:69
FILE * tmpFH
Definition: pg_backup_tar.c:70
pgoff_t tarFHpos
Definition: pg_backup_tar.c:84
#define ftello(stream)
Definition: win32_port.h:219
#define fseeko(stream, offset, origin)
Definition: win32_port.h:216

References _tarWriteHeader(), buf, TAR_MEMBER::fileLen, _archiveHandle::formatData, fseeko, ftello, i, if(), len, pg_fatal, pgoff_t, READ_ERROR_EXIT, res, TAR_MEMBER::tarFH, lclContext::tarFHpos, tarPaddingBytesRequired(), TAR_MEMBER::tmpFH, and WRITE_ERROR_EXIT.

Referenced by tarClose().

◆ _tarGetHeader()

static int _tarGetHeader ( ArchiveHandle AH,
TAR_MEMBER th 
)
static

Definition at line 1140 of file pg_backup_tar.c.

1141{
1142 lclContext *ctx = (lclContext *) AH->formatData;
1143 char h[TAR_BLOCK_SIZE];
1144 char tag[100 + 1];
1145 int sum,
1146 chk;
1147 pgoff_t len;
1148 pgoff_t hPos;
1149 bool gotBlock = false;
1150
1151 while (!gotBlock)
1152 {
1153 /* Save the pos for reporting purposes */
1154 hPos = ctx->tarFHpos;
1155
1156 /* Read the next tar block, return EOF, exit if short */
1157 len = _tarReadRaw(AH, h, TAR_BLOCK_SIZE, NULL, ctx->tarFH);
1158 if (len == 0) /* EOF */
1159 return 0;
1160
1161 if (len != TAR_BLOCK_SIZE)
1162 pg_fatal(ngettext("incomplete tar header found (%lu byte)",
1163 "incomplete tar header found (%lu bytes)",
1164 len),
1165 (unsigned long) len);
1166
1167 /* Calc checksum */
1168 chk = tarChecksum(h);
1170
1171 /*
1172 * If the checksum failed, see if it is a null block. If so, silently
1173 * continue to the next block.
1174 */
1175 if (chk == sum)
1176 gotBlock = true;
1177 else
1178 {
1179 int i;
1180
1181 for (i = 0; i < TAR_BLOCK_SIZE; i++)
1182 {
1183 if (h[i] != 0)
1184 {
1185 gotBlock = true;
1186 break;
1187 }
1188 }
1189 }
1190 }
1191
1192 /* Name field is 100 bytes, might not be null-terminated */
1193 strlcpy(tag, &h[TAR_OFFSET_NAME], 100 + 1);
1194
1196
1197 pg_log_debug("TOC Entry %s at %llu (length %llu, checksum %d)",
1198 tag, (unsigned long long) hPos, (unsigned long long) len, sum);
1199
1200 if (chk != sum)
1201 pg_fatal("corrupt tar header found in %s (expected %d, computed %d) file position %llu",
1202 tag, sum, chk, (unsigned long long) ftello(ctx->tarFH));
1203
1204 th->targetFile = pg_strdup(tag);
1205 th->fileLen = len;
1206
1207 return 1;
1208}
#define ngettext(s, p, n)
Definition: c.h:1135
#define pg_log_debug(...)
Definition: logging.h:133
static size_t _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
while(p+4<=pend)
uint64 read_tar_number(const char *s, int len)
Definition: tar.c:58
int tarChecksum(char *header)
Definition: tar.c:90
@ TAR_OFFSET_NAME
Definition: pgtar.h:39
@ TAR_OFFSET_SIZE
Definition: pgtar.h:43
@ TAR_OFFSET_CHECKSUM
Definition: pgtar.h:45
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * targetFile
Definition: pg_backup_tar.c:71

References _tarReadRaw(), TAR_MEMBER::fileLen, _archiveHandle::formatData, ftello, i, len, ngettext, pg_fatal, pg_log_debug, pg_strdup(), pgoff_t, read_tar_number(), strlcpy(), TAR_BLOCK_SIZE, TAR_OFFSET_CHECKSUM, TAR_OFFSET_NAME, TAR_OFFSET_SIZE, tarChecksum(), lclContext::tarFH, lclContext::tarFHpos, TAR_MEMBER::targetFile, and while().

Referenced by _tarPositionTo().

◆ _tarPositionTo()

static TAR_MEMBER * _tarPositionTo ( ArchiveHandle AH,
const char *  filename 
)
static

Definition at line 1066 of file pg_backup_tar.c.

1067{
1068 lclContext *ctx = (lclContext *) AH->formatData;
1070 char c;
1071 char header[TAR_BLOCK_SIZE];
1072 size_t i,
1073 len,
1074 blks;
1075 int id;
1076
1077 th->AH = AH;
1078
1079 /* Go to end of current file, if any */
1080 if (ctx->tarFHpos != 0)
1081 {
1082 pg_log_debug("moving from position %lld to next member at file position %lld",
1083 (long long) ctx->tarFHpos, (long long) ctx->tarNextMember);
1084
1085 while (ctx->tarFHpos < ctx->tarNextMember)
1086 _tarReadRaw(AH, &c, 1, NULL, ctx->tarFH);
1087 }
1088
1089 pg_log_debug("now at file position %lld", (long long) ctx->tarFHpos);
1090
1091 /* We are at the start of the file, or at the next member */
1092
1093 /* Get the header */
1094 if (!_tarGetHeader(AH, th))
1095 {
1096 if (filename)
1097 pg_fatal("could not find header for file \"%s\" in tar archive", filename);
1098 else
1099 {
1100 /*
1101 * We're just scanning the archive for the next file, so return
1102 * null
1103 */
1104 free(th);
1105 return NULL;
1106 }
1107 }
1108
1109 while (filename != NULL && strcmp(th->targetFile, filename) != 0)
1110 {
1111 pg_log_debug("skipping tar member %s", th->targetFile);
1112
1113 id = atoi(th->targetFile);
1114 if ((TocIDRequired(AH, id) & REQ_DATA) != 0)
1115 pg_fatal("restoring data out of order is not supported in this archive format: "
1116 "\"%s\" is required, but comes before \"%s\" in the archive file.",
1117 th->targetFile, filename);
1118
1119 /* Header doesn't match, so read to next header */
1120 len = th->fileLen;
1121 len += tarPaddingBytesRequired(th->fileLen);
1122 blks = len / TAR_BLOCK_SIZE; /* # of tar blocks */
1123
1124 for (i = 0; i < blks; i++)
1125 _tarReadRaw(AH, &header[0], TAR_BLOCK_SIZE, NULL, ctx->tarFH);
1126
1127 if (!_tarGetHeader(AH, th))
1128 pg_fatal("could not find header for file \"%s\" in tar archive", filename);
1129 }
1130
1131 ctx->tarNextMember = ctx->tarFHpos + th->fileLen
1132 + tarPaddingBytesRequired(th->fileLen);
1133 th->pos = 0;
1134
1135 return th;
1136}
int TocIDRequired(ArchiveHandle *AH, DumpId id)
#define REQ_DATA
static int _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
pgoff_t tarNextMember
Definition: pg_backup_tar.c:85

References _tarGetHeader(), _tarReadRaw(), TAR_MEMBER::AH, TAR_MEMBER::fileLen, filename, _archiveHandle::formatData, free, i, len, pg_fatal, pg_log_debug, pg_malloc0_object, TAR_MEMBER::pos, REQ_DATA, TAR_BLOCK_SIZE, lclContext::tarFH, lclContext::tarFHpos, TAR_MEMBER::targetFile, lclContext::tarNextMember, tarPaddingBytesRequired(), and TocIDRequired().

Referenced by tarOpen().

◆ _tarReadRaw()

static size_t _tarReadRaw ( ArchiveHandle AH,
void *  buf,
size_t  len,
TAR_MEMBER th,
FILE *  fh 
)
static

Definition at line 462 of file pg_backup_tar.c.

463{
464 lclContext *ctx = (lclContext *) AH->formatData;
465 size_t avail;
466 size_t used = 0;
467 size_t res = 0;
468
469 Assert(th || fh);
470
471 avail = AH->lookaheadLen - AH->lookaheadPos;
472 if (avail > 0)
473 {
474 /* We have some lookahead bytes to use */
475 if (avail >= len) /* Just use the lookahead buffer */
476 used = len;
477 else
478 used = avail;
479
480 /* Copy, and adjust buffer pos */
481 memcpy(buf, AH->lookahead + AH->lookaheadPos, used);
482 AH->lookaheadPos += used;
483
484 /* Adjust required length */
485 len -= used;
486 }
487
488 /* Read the file if len > 0 */
489 if (len > 0)
490 {
491 if (fh)
492 {
493 res = fread(&((char *) buf)[used], 1, len, fh);
494 if (res != len && !feof(fh))
495 READ_ERROR_EXIT(fh);
496 }
497 else if (th)
498 {
499 res = fread(&((char *) buf)[used], 1, len, th->nFH);
500 if (res != len && !feof(th->nFH))
501 READ_ERROR_EXIT(th->nFH);
502 }
503 }
504
505 ctx->tarFHpos += res + used;
506
507 return (res + used);
508}
#define Assert(condition)
Definition: c.h:812
FILE * nFH
Definition: pg_backup_tar.c:68

References Assert, buf, _archiveHandle::formatData, len, _archiveHandle::lookahead, _archiveHandle::lookaheadLen, _archiveHandle::lookaheadPos, TAR_MEMBER::nFH, READ_ERROR_EXIT, res, and lclContext::tarFHpos.

Referenced by _tarGetHeader(), _tarPositionTo(), and tarRead().

◆ _tarWriteHeader()

static void _tarWriteHeader ( TAR_MEMBER th)
static

Definition at line 1212 of file pg_backup_tar.c.

1213{
1214 char h[TAR_BLOCK_SIZE];
1215
1216 tarCreateHeader(h, th->targetFile, NULL, th->fileLen,
1217 0600, 04000, 02000, time(NULL));
1218
1219 /* Now write the completed header. */
1220 if (fwrite(h, 1, TAR_BLOCK_SIZE, th->tarFH) != TAR_BLOCK_SIZE)
1222}
enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime)
Definition: tar.c:114

References TAR_MEMBER::fileLen, TAR_BLOCK_SIZE, tarCreateHeader(), TAR_MEMBER::tarFH, TAR_MEMBER::targetFile, and WRITE_ERROR_EXIT.

Referenced by _tarAddFile().

◆ _WriteBuf()

static void _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 746 of file pg_backup_tar.c.

747{
748 lclContext *ctx = (lclContext *) AH->formatData;
749
750 if (tarWrite(buf, len, ctx->FH) != len)
752
753 ctx->filePos += len;
754}

References buf, lclContext::FH, lclContext::filePos, _archiveHandle::formatData, if(), len, tarWrite(), and WRITE_ERROR_EXIT.

Referenced by InitArchiveFmt_Tar().

◆ _WriteByte()

static int _WriteByte ( ArchiveHandle AH,
const int  i 
)
static

Definition at line 718 of file pg_backup_tar.c.

719{
720 lclContext *ctx = (lclContext *) AH->formatData;
721 char b = i; /* Avoid endian problems */
722
723 if (tarWrite(&b, 1, ctx->FH) != 1)
725
726 ctx->filePos += 1;
727 return 1;
728}
int b
Definition: isn.c:69

References b, lclContext::FH, lclContext::filePos, _archiveHandle::formatData, i, if(), tarWrite(), and WRITE_ERROR_EXIT.

Referenced by InitArchiveFmt_Tar().

◆ _WriteData()

static void _WriteData ( ArchiveHandle AH,
const void *  data,
size_t  dLen 
)
static

Definition at line 540 of file pg_backup_tar.c.

541{
542 lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
543
544 if (tarWrite(data, dLen, tctx->TH) != dLen)
546}
const void * data
struct _tocEntry * currToc

References _archiveHandle::currToc, data, _tocEntry::formatData, if(), tarWrite(), lclTocEntry::TH, and WRITE_ERROR_EXIT.

Referenced by InitArchiveFmt_Tar().

◆ _WriteExtraToc()

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 254 of file pg_backup_tar.c.

255{
256 lclTocEntry *ctx = (lclTocEntry *) te->formatData;
257
258 if (ctx->filename)
259 WriteStr(AH, ctx->filename);
260 else
261 WriteStr(AH, "");
262}
size_t WriteStr(ArchiveHandle *AH, const char *c)

References lclTocEntry::filename, _tocEntry::formatData, if(), and WriteStr().

Referenced by InitArchiveFmt_Tar().

◆ InitArchiveFmt_Tar()

void InitArchiveFmt_Tar ( ArchiveHandle AH)

Definition at line 121 of file pg_backup_tar.c.

122{
123 lclContext *ctx;
124
125 /* Assuming static functions, this can be copied for each format. */
129 AH->EndDataPtr = _EndData;
133 AH->ReadBufPtr = _ReadBuf;
135 AH->ReopenPtr = NULL;
140
142 AH->StartLOPtr = _StartLO;
143 AH->EndLOPtr = _EndLO;
144 AH->EndLOsPtr = _EndLOs;
145 AH->ClonePtr = NULL;
146 AH->DeClonePtr = NULL;
147
148 AH->WorkerJobDumpPtr = NULL;
149 AH->WorkerJobRestorePtr = NULL;
150
151 /*
152 * Set up some special context used in compressing data.
153 */
155 AH->formatData = ctx;
156 ctx->filePos = 0;
157 ctx->isSpecialScript = 0;
158
159 /*
160 * Now open the tar file, and load the TOC if we're in read mode.
161 */
162 if (AH->mode == archModeWrite)
163 {
164 if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
165 {
166 ctx->tarFH = fopen(AH->fSpec, PG_BINARY_W);
167 if (ctx->tarFH == NULL)
168 pg_fatal("could not open TOC file \"%s\" for output: %m",
169 AH->fSpec);
170 }
171 else
172 {
173 ctx->tarFH = stdout;
174 if (ctx->tarFH == NULL)
175 pg_fatal("could not open TOC file for output: %m");
176 }
177
178 ctx->tarFHpos = 0;
179
180 /*
181 * Make unbuffered since we will dup() it, and the buffers screw each
182 * other
183 */
184 /* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
185
186 ctx->hasSeek = checkSeek(ctx->tarFH);
187
188 /*
189 * We don't support compression because reading the files back is not
190 * possible since gzdopen uses buffered IO which totally screws file
191 * positioning.
192 */
194 pg_fatal("compression is not supported by tar archive format");
195 }
196 else
197 { /* Read Mode */
198 if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
199 {
200 ctx->tarFH = fopen(AH->fSpec, PG_BINARY_R);
201 if (ctx->tarFH == NULL)
202 pg_fatal("could not open TOC file \"%s\" for input: %m",
203 AH->fSpec);
204 }
205 else
206 {
207 ctx->tarFH = stdin;
208 if (ctx->tarFH == NULL)
209 pg_fatal("could not open TOC file for input: %m");
210 }
211
212 /*
213 * Make unbuffered since we will dup() it, and the buffers screw each
214 * other
215 */
216 /* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
217
218 ctx->tarFHpos = 0;
219
220 ctx->hasSeek = checkSeek(ctx->tarFH);
221
222 ctx->FH = tarOpen(AH, "toc.dat", 'r');
223 ReadHead(AH);
224 ReadToc(AH);
225 tarClose(AH, ctx->FH); /* Nothing else in the file... */
226 }
227}
#define PG_BINARY_R
Definition: c.h:1229
#define PG_BINARY_W
Definition: c.h:1230
bool checkSeek(FILE *fp)
void ReadHead(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
static void _StartData(ArchiveHandle *AH, TocEntry *te)
static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _CloseArchive(ArchiveHandle *AH)
static void _StartLOs(ArchiveHandle *AH, TocEntry *te)
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _EndLOs(ArchiveHandle *AH, TocEntry *te)
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
static int _ReadByte(ArchiveHandle *AH)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
DeClonePtrType DeClonePtr
EndLOsPtrType EndLOsPtr
ReadExtraTocPtrType ReadExtraTocPtr
WorkerJobDumpPtrType WorkerJobDumpPtr
StartLOsPtrType StartLOsPtr
ArchiveEntryPtrType ArchiveEntryPtr
WriteDataPtrType WriteDataPtr
StartLOPtrType StartLOPtr
ClonePtrType ClonePtr
WriteBufPtrType WriteBufPtr
EndLOPtrType EndLOPtr
WriteExtraTocPtrType WriteExtraTocPtr
ReadBytePtrType ReadBytePtr
WorkerJobRestorePtrType WorkerJobRestorePtr
PrintTocDataPtrType PrintTocDataPtr
WriteBytePtrType WriteBytePtr
ReadBufPtrType ReadBufPtr
PrintExtraTocPtrType PrintExtraTocPtr
StartDataPtrType StartDataPtr
ReopenPtrType ReopenPtr
EndDataPtrType EndDataPtr
ClosePtrType ClosePtr

References _ArchiveEntry(), _CloseArchive(), _EndData(), _EndLO(), _EndLOs(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _StartData(), _StartLO(), _StartLOs(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), archModeWrite, checkSeek(), lclContext::FH, lclContext::filePos, lclContext::hasSeek, lclContext::isSpecialScript, PG_BINARY_R, PG_BINARY_W, PG_COMPRESSION_NONE, pg_fatal, pg_malloc0_object, ReadHead(), ReadToc(), generate_unaccent_rules::stdout, tarClose(), lclContext::tarFH, lclContext::tarFHpos, and tarOpen().

Referenced by _allocAH().

◆ isValidTarHeader()

bool isValidTarHeader ( char *  header)

Definition at line 988 of file pg_backup_tar.c.

989{
990 int sum;
991 int chk = tarChecksum(header);
992
993 sum = read_tar_number(&header[TAR_OFFSET_CHECKSUM], 8);
994
995 if (sum != chk)
996 return false;
997
998 /* POSIX tar format */
999 if (memcmp(&header[TAR_OFFSET_MAGIC], "ustar\0", 6) == 0 &&
1000 memcmp(&header[TAR_OFFSET_VERSION], "00", 2) == 0)
1001 return true;
1002 /* GNU tar format */
1003 if (memcmp(&header[TAR_OFFSET_MAGIC], "ustar \0", 8) == 0)
1004 return true;
1005 /* not-quite-POSIX format written by pre-9.3 pg_dump */
1006 if (memcmp(&header[TAR_OFFSET_MAGIC], "ustar00\0", 8) == 0)
1007 return true;
1008
1009 return false;
1010}
@ TAR_OFFSET_VERSION
Definition: pgtar.h:49
@ TAR_OFFSET_MAGIC
Definition: pgtar.h:48

References read_tar_number(), TAR_OFFSET_CHECKSUM, TAR_OFFSET_MAGIC, TAR_OFFSET_VERSION, and tarChecksum().

Referenced by _discoverArchiveFormat().

◆ tarClose()

static void tarClose ( ArchiveHandle AH,
TAR_MEMBER th 
)
static

Definition at line 398 of file pg_backup_tar.c.

399{
401 pg_fatal("compression is not supported by tar archive format");
402
403 if (th->mode == 'w')
404 _tarAddFile(AH, th); /* This will close the temp file */
405
406 /*
407 * else Nothing to do for normal read since we don't dup() normal file
408 * handle, and we don't use temp files.
409 */
410
411 free(th->targetFile);
412
413 th->nFH = NULL;
414}
static int static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)

References _tarAddFile(), pg_compress_specification::algorithm, _archiveHandle::compression_spec, free, TAR_MEMBER::mode, TAR_MEMBER::nFH, PG_COMPRESSION_NONE, pg_fatal, and TAR_MEMBER::targetFile.

Referenced by _CloseArchive(), _EndData(), _EndLO(), _EndLOs(), _LoadLOs(), _PrintFileData(), and InitArchiveFmt_Tar().

◆ tarOpen()

static TAR_MEMBER * tarOpen ( ArchiveHandle AH,
const char *  filename,
char  mode 
)
static

Definition at line 302 of file pg_backup_tar.c.

303{
304 lclContext *ctx = (lclContext *) AH->formatData;
305 TAR_MEMBER *tm;
306
307 if (mode == 'r')
308 {
310 if (!tm) /* Not found */
311 {
312 if (filename)
313 {
314 /*
315 * Couldn't find the requested file. Future: do SEEK(0) and
316 * retry.
317 */
318 pg_fatal("could not find file \"%s\" in archive", filename);
319 }
320 else
321 {
322 /* Any file OK, none left, so return NULL */
323 return NULL;
324 }
325 }
326
328 tm->nFH = ctx->tarFH;
329 else
330 pg_fatal("compression is not supported by tar archive format");
331 }
332 else
333 {
334 int old_umask;
335
337
338 /*
339 * POSIX does not require, but permits, tmpfile() to restrict file
340 * permissions. Given an OS crash after we write data, the filesystem
341 * might retain the data but forget tmpfile()'s unlink(). If so, the
342 * file mode protects confidentiality of the data written.
343 */
344 old_umask = umask(S_IRWXG | S_IRWXO);
345
346#ifndef WIN32
347 tm->tmpFH = tmpfile();
348#else
349
350 /*
351 * On WIN32, tmpfile() generates a filename in the root directory,
352 * which requires administrative permissions on certain systems. Loop
353 * until we find a unique file name we can create.
354 */
355 while (1)
356 {
357 char *name;
358 int fd;
359
360 name = _tempnam(NULL, "pg_temp_");
361 if (name == NULL)
362 break;
363 fd = open(name, O_RDWR | O_CREAT | O_EXCL | O_BINARY |
364 O_TEMPORARY, S_IRUSR | S_IWUSR);
365 free(name);
366
367 if (fd != -1) /* created a file */
368 {
369 tm->tmpFH = fdopen(fd, "w+b");
370 break;
371 }
372 else if (errno != EEXIST) /* failure other than file exists */
373 break;
374 }
375#endif
376
377 if (tm->tmpFH == NULL)
378 pg_fatal("could not generate temporary file name: %m");
379
380 umask(old_umask);
381
383 tm->nFH = tm->tmpFH;
384 else
385 pg_fatal("compression is not supported by tar archive format");
386
387 tm->AH = AH;
388 tm->targetFile = pg_strdup(filename);
389 }
390
391 tm->mode = mode;
392 tm->tarFH = ctx->tarFH;
393
394 return tm;
395}
static struct pg_tm tm
Definition: localtime.c:104
static TAR_MEMBER * _tarPositionTo(ArchiveHandle *AH, const char *filename)
static PgChecksumMode mode
Definition: pg_checksums.c:55
static int fd(const char *x, int i)
Definition: preproc-init.c:105
const char * name
#define S_IRWXG
Definition: win32_port.h:310
#define S_IRWXO
Definition: win32_port.h:322
#define S_IRUSR
Definition: win32_port.h:289
#define S_IWUSR
Definition: win32_port.h:292

References _tarPositionTo(), pg_compress_specification::algorithm, _archiveHandle::compression_spec, fd(), filename, _archiveHandle::formatData, free, if(), mode, name, PG_COMPRESSION_NONE, pg_fatal, pg_malloc0_object, pg_strdup(), S_IRUSR, S_IRWXG, S_IRWXO, S_IWUSR, lclContext::tarFH, and tm.

Referenced by _CloseArchive(), _LoadLOs(), _PrintFileData(), _StartData(), _StartLO(), _StartLOs(), and InitArchiveFmt_Tar().

◆ tarPrintf()

static int tarPrintf ( TAR_MEMBER th,
const char *  fmt,
  ... 
)
static

Definition at line 954 of file pg_backup_tar.c.

955{
956 int save_errno = errno;
957 char *p;
958 size_t len = 128; /* initial assumption about buffer size */
959 size_t cnt;
960
961 for (;;)
962 {
963 va_list args;
964
965 /* Allocate work buffer. */
966 p = (char *) pg_malloc(len);
967
968 /* Try to format the data. */
969 errno = save_errno;
970 va_start(args, fmt);
971 cnt = pvsnprintf(p, len, fmt, args);
972 va_end(args);
973
974 if (cnt < len)
975 break; /* success */
976
977 /* Release buffer and loop around to try again with larger len. */
978 free(p);
979 len = cnt;
980 }
981
982 cnt = tarWrite(p, cnt, th);
983 free(p);
984 return (int) cnt;
985}
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static void const char * fmt
va_end(args)
va_start(args, fmt)
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:103

References generate_unaccent_rules::args, fmt, free, len, pg_malloc(), pvsnprintf(), tarWrite(), va_end(), and va_start().

Referenced by _CloseArchive(), and _StartLO().

◆ tarRead()

static size_t tarRead ( void *  buf,
size_t  len,
TAR_MEMBER th 
)
static

Definition at line 511 of file pg_backup_tar.c.

512{
513 size_t res;
514
515 if (th->pos + len > th->fileLen)
516 len = th->fileLen - th->pos;
517
518 if (len <= 0)
519 return 0;
520
521 res = _tarReadRaw(th->AH, buf, len, th, NULL);
522
523 th->pos += res;
524
525 return res;
526}
pgoff_t pos
Definition: pg_backup_tar.c:73
ArchiveHandle * AH
Definition: pg_backup_tar.c:75

References _tarReadRaw(), TAR_MEMBER::AH, buf, TAR_MEMBER::fileLen, len, TAR_MEMBER::pos, and res.

Referenced by _LoadLOs(), _PrintFileData(), _ReadBuf(), and _ReadByte().

◆ tarWrite()

static size_t tarWrite ( const void *  buf,
size_t  len,
TAR_MEMBER th 
)
static

Definition at line 529 of file pg_backup_tar.c.

530{
531 size_t res;
532
533 res = fwrite(buf, 1, len, th->nFH);
534
535 th->pos += res;
536 return res;
537}

References buf, len, TAR_MEMBER::nFH, TAR_MEMBER::pos, and res.

Referenced by _scriptOut(), _WriteBuf(), _WriteByte(), _WriteData(), and tarPrintf().