PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_backup_tar.c File Reference
#include "postgres_fe.h"
#include "pg_backup_archiver.h"
#include "pg_backup_tar.h"
#include "pg_backup_utils.h"
#include "pgtar.h"
#include "fe_utils/string_utils.h"
#include <sys/stat.h>
#include <ctype.h>
#include <limits.h>
#include <unistd.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 *)
 
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 _StartBlobs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndBlobs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadBlobs (ArchiveHandle *AH)
 
static TAR_MEMBERtarOpen (ArchiveHandle *AH, const char *filename, char mode)
 
static void tarClose (ArchiveHandle *AH, TAR_MEMBER *TH)
 
static int tarPrintf (ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(3
 
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)
 

Variables

static const char * modulename = gettext_noop("tar archiver")
 

Macro Definition Documentation

#define K_STD_BUF_SIZE   1024

Definition at line 62 of file pg_backup_tar.c.

Referenced by _ArchiveEntry(), and _StartBlobs().

Function Documentation

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 256 of file pg_backup_tar.c.

References _archiveHandle::compression, _tocEntry::dataDumper, _tocEntry::dumpId, lclTocEntry::filename, fn(), _tocEntry::formatData, K_STD_BUF_SIZE, NULL, pg_malloc0(), pg_strdup(), and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

257 {
258  lclTocEntry *ctx;
259  char fn[K_STD_BUF_SIZE];
260 
261  ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
262  if (te->dataDumper != NULL)
263  {
264 #ifdef HAVE_LIBZ
265  if (AH->compression == 0)
266  sprintf(fn, "%d.dat", te->dumpId);
267  else
268  sprintf(fn, "%d.dat.gz", te->dumpId);
269 #else
270  sprintf(fn, "%d.dat", te->dumpId);
271 #endif
272  ctx->filename = pg_strdup(fn);
273  }
274  else
275  {
276  ctx->filename = NULL;
277  ctx->TH = NULL;
278  }
279  te->formatData = (void *) ctx;
280 }
DataDumperPtr dataDumper
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void * fn(void *arg)
#define NULL
Definition: c.h:226
#define K_STD_BUF_SIZE
Definition: pg_backup_tar.c:62
TAR_MEMBER * TH
Definition: pg_backup_tar.c:97
static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 825 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

826 {
827  lclContext *ctx = (lclContext *) AH->formatData;
828  TAR_MEMBER *th;
829  RestoreOptions *ropt;
830  RestoreOptions *savRopt;
831  DumpOptions *savDopt;
832  int savVerbose,
833  i;
834 
835  if (AH->mode == archModeWrite)
836  {
837  /*
838  * Write the Header & TOC to the archive FIRST
839  */
840  th = tarOpen(AH, "toc.dat", 'w');
841  ctx->FH = th;
842  WriteHead(AH);
843  WriteToc(AH);
844  tarClose(AH, th); /* Not needed any more */
845 
846  /*
847  * Now send the data (tables & blobs)
848  */
849  WriteDataChunks(AH, NULL);
850 
851  /*
852  * Now this format wants to append a script which does a full restore
853  * if the files have been extracted.
854  */
855  th = tarOpen(AH, "restore.sql", 'w');
856 
857  tarPrintf(AH, th, "--\n"
858  "-- NOTE:\n"
859  "--\n"
860  "-- File paths need to be edited. Search for $$PATH$$ and\n"
861  "-- replace it with the path to the directory containing\n"
862  "-- the extracted data files.\n"
863  "--\n");
864 
865  AH->CustomOutPtr = _scriptOut;
866 
867  ctx->isSpecialScript = 1;
868  ctx->scriptTH = th;
869 
870  ropt = NewRestoreOptions();
871  memcpy(ropt, AH->public.ropt, sizeof(RestoreOptions));
872  ropt->filename = NULL;
873  ropt->dropSchema = 1;
874  ropt->compression = 0;
875  ropt->superuser = NULL;
876  ropt->suppressDumpWarnings = true;
877 
878  savDopt = AH->public.dopt;
879  savRopt = AH->public.ropt;
880 
881  SetArchiveOptions((Archive *) AH, NULL, ropt);
882 
883  savVerbose = AH->public.verbose;
884  AH->public.verbose = 0;
885 
886  RestoreArchive((Archive *) AH);
887 
888  SetArchiveOptions((Archive *) AH, savDopt, savRopt);
889 
890  AH->public.verbose = savVerbose;
891 
892  tarClose(AH, th);
893 
894  ctx->isSpecialScript = 0;
895 
896  /*
897  * EOF marker for tar files is two blocks of NULLs.
898  */
899  for (i = 0; i < 512 * 2; i++)
900  {
901  if (fputc(0, ctx->tarFH) == EOF)
903  }
904  }
905 
906  AH->FH = NULL;
907 }
static int tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(3
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
TAR_MEMBER * scriptTH
Definition: pg_backup_tar.c:92
RestoreOptions * ropt
Definition: pg_backup.h:179
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void WriteToc(ArchiveHandle *AH)
RestoreOptions * NewRestoreOptions(void)
int isSpecialScript
Definition: pg_backup_tar.c:91
DumpOptions * dopt
Definition: pg_backup.h:178
FILE * tarFH
Definition: pg_backup_tar.c:87
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
CustomOutPtr CustomOutPtr
int verbose
Definition: pg_backup.h:181
static size_t _scriptOut(ArchiveHandle *AH, const void *buf, size_t len)
#define NULL
Definition: c.h:226
void WriteHead(ArchiveHandle *AH)
#define WRITE_ERROR_EXIT
void RestoreArchive(Archive *AH)
int i
void SetArchiveOptions(Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
static void _EndBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 978 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

979 {
980  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
981 
982  tarClose(AH, tctx->TH);
983 }
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
TAR_MEMBER * TH
Definition: pg_backup_tar.c:97
static void _EndBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 992 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

993 {
994  lclContext *ctx = (lclContext *) AH->formatData;
995 
996  /* Write out a fake zero OID to mark end-of-blobs. */
997  /* WriteInt(AH, 0); */
998 
999  tarClose(AH, ctx->blobToc);
1000 }
TAR_MEMBER * blobToc
Definition: pg_backup_tar.c:86
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 620 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

621 {
622  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
623 
624  /* Close the file */
625  tarClose(AH, tctx->TH);
626  tctx->TH = NULL;
627 }
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
#define NULL
Definition: c.h:226
TAR_MEMBER * TH
Definition: pg_backup_tar.c:97
static void _LoadBlobs ( ArchiveHandle AH)
static

Definition at line 715 of file pg_backup_tar.c.

References ahlog(), ahwrite(), atooid, _restoreOptions::dropSchema, EndRestoreBlob(), EndRestoreBlobs(), lclContext::FH, _archiveHandle::formatData, NULL, _archiveHandle::public, Archive::ropt, StartRestoreBlob(), StartRestoreBlobs(), tarClose(), TAR_MEMBER::targetFile, tarOpen(), and tarRead().

Referenced by _PrintTocData().

716 {
717  Oid oid;
718  lclContext *ctx = (lclContext *) AH->formatData;
719  TAR_MEMBER *th;
720  size_t cnt;
721  bool foundBlob = false;
722  char buf[4096];
723 
724  StartRestoreBlobs(AH);
725 
726  th = tarOpen(AH, NULL, 'r'); /* Open next file */
727  while (th != NULL)
728  {
729  ctx->FH = th;
730 
731  if (strncmp(th->targetFile, "blob_", 5) == 0)
732  {
733  oid = atooid(&th->targetFile[5]);
734  if (oid != 0)
735  {
736  ahlog(AH, 1, "restoring large object with OID %u\n", oid);
737 
738  StartRestoreBlob(AH, oid, AH->public.ropt->dropSchema);
739 
740  while ((cnt = tarRead(buf, 4095, th)) > 0)
741  {
742  buf[cnt] = '\0';
743  ahwrite(buf, 1, cnt, AH);
744  }
745  EndRestoreBlob(AH, oid);
746  foundBlob = true;
747  }
748  tarClose(AH, th);
749  }
750  else
751  {
752  tarClose(AH, th);
753 
754  /*
755  * Once we have found the first blob, stop at the first non-blob
756  * entry (which will be 'blobs.toc'). This coding would eat all
757  * the rest of the archive if there are no blobs ... but this
758  * function shouldn't be called at all in that case.
759  */
760  if (foundBlob)
761  break;
762  }
763 
764  th = tarOpen(AH, NULL, 'r');
765  }
766  EndRestoreBlobs(AH);
767 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
RestoreOptions * ropt
Definition: pg_backup.h:179
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
unsigned int Oid
Definition: postgres_ext.h:31
void StartRestoreBlobs(ArchiveHandle *AH)
void StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
static char * buf
Definition: pg_test_fsync.c:65
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
void EndRestoreBlobs(ArchiveHandle *AH)
#define NULL
Definition: c.h:226
#define atooid(x)
Definition: lo.c:17
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
void EndRestoreBlob(ArchiveHandle *AH, Oid oid)
static size_t tarRead(void *buf, size_t len, TAR_MEMBER *th)
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 314 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

315 {
316  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
317 
318  if (AH->public.verbose && ctx->filename != NULL)
319  ahprintf(AH, "-- File: %s\n", ctx->filename);
320 }
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
int verbose
Definition: pg_backup.h:181
#define NULL
Definition: c.h:226
static void _PrintFileData ( ArchiveHandle AH,
char *  filename 
)
static

Definition at line 633 of file pg_backup_tar.c.

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

Referenced by _PrintTocData().

634 {
635  lclContext *ctx = (lclContext *) AH->formatData;
636  char buf[4096];
637  size_t cnt;
638  TAR_MEMBER *th;
639 
640  if (!filename)
641  return;
642 
643  th = tarOpen(AH, filename, 'r');
644  ctx->FH = th;
645 
646  while ((cnt = tarRead(buf, 4095, th)) > 0)
647  {
648  buf[cnt] = '\0';
649  ahwrite(buf, 1, cnt, AH);
650  }
651 
652  tarClose(AH, th);
653 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
static char * buf
Definition: pg_test_fsync.c:65
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
static char * filename
Definition: pg_dumpall.c:84
static size_t tarRead(void *buf, size_t len, TAR_MEMBER *th)
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 660 of file pg_backup_tar.c.

References _LoadBlobs(), _PrintFileData(), ahprintf(), ahwrite(), _tocEntry::copyStmt, _tocEntry::desc, exit_horribly(), _archiveHandle::formatData, _tocEntry::formatData, lclContext::isSpecialScript, and modulename.

Referenced by InitArchiveFmt_Tar().

661 {
662  lclContext *ctx = (lclContext *) AH->formatData;
663  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
664  int pos1;
665 
666  if (!tctx->filename)
667  return;
668 
669  /*
670  * If we're writing the special restore.sql script, emit a suitable
671  * command to include each table's data from the corresponding file.
672  *
673  * In the COPY case this is a bit klugy because the regular COPY command
674  * was already printed before we get control.
675  */
676  if (ctx->isSpecialScript)
677  {
678  if (te->copyStmt)
679  {
680  /* Abort the COPY FROM stdin */
681  ahprintf(AH, "\\.\n");
682 
683  /*
684  * The COPY statement should look like "COPY ... FROM stdin;\n",
685  * see dumpTableData().
686  */
687  pos1 = (int) strlen(te->copyStmt) - 13;
688  if (pos1 < 6 || strncmp(te->copyStmt, "COPY ", 5) != 0 ||
689  strcmp(te->copyStmt + pos1, " FROM stdin;\n") != 0)
691  "unexpected COPY statement syntax: \"%s\"\n",
692  te->copyStmt);
693 
694  /* Emit all but the FROM part ... */
695  ahwrite(te->copyStmt, 1, pos1, AH);
696  /* ... and insert modified FROM */
697  ahprintf(AH, " FROM '$$PATH$$/%s';\n\n", tctx->filename);
698  }
699  else
700  {
701  /* --inserts mode, no worries, just include the data file */
702  ahprintf(AH, "\\i $$PATH$$/%s\n\n", tctx->filename);
703  }
704 
705  return;
706  }
707 
708  if (strcmp(te->desc, "BLOBS") == 0)
709  _LoadBlobs(AH);
710  else
711  _PrintFileData(AH, tctx->filename);
712 }
static void _LoadBlobs(ArchiveHandle *AH)
static void _PrintFileData(ArchiveHandle *AH, char *filename)
int isSpecialScript
Definition: pg_backup_tar.c:91
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
static const char * modulename
void exit_horribly(const char *modulename, const char *fmt,...)
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
static void _ReadBuf ( ArchiveHandle AH,
void *  buf,
size_t  len 
)
static

Definition at line 811 of file pg_backup_tar.c.

References exit_horribly(), lclContext::FH, lclContext::filePos, _archiveHandle::formatData, modulename, and tarRead().

Referenced by InitArchiveFmt_Tar().

812 {
813  lclContext *ctx = (lclContext *) AH->formatData;
814 
815  if (tarRead(buf, len, ctx->FH) != len)
816  /* We already would have exited for errors on reads, must be EOF */
818  "could not read from input file: end of file\n");
819 
820  ctx->filePos += len;
821  return;
822 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
static char * buf
Definition: pg_test_fsync.c:65
static const char * modulename
void exit_horribly(const char *modulename, const char *fmt,...)
static size_t tarRead(void *buf, size_t len, TAR_MEMBER *th)
pgoff_t filePos
static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 784 of file pg_backup_tar.c.

References exit_horribly(), lclContext::FH, lclContext::filePos, _archiveHandle::formatData, modulename, and tarRead().

Referenced by InitArchiveFmt_Tar().

785 {
786  lclContext *ctx = (lclContext *) AH->formatData;
787  size_t res;
788  unsigned char c;
789 
790  res = tarRead(&c, 1, ctx->FH);
791  if (res != 1)
792  /* We already would have exited for errors on reads, must be EOF */
794  "could not read from input file: end of file\n");
795  ctx->filePos += 1;
796  return c;
797 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
char * c
static const char * modulename
void exit_horribly(const char *modulename, const char *fmt,...)
static size_t tarRead(void *buf, size_t len, TAR_MEMBER *th)
pgoff_t filePos
static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 294 of file pg_backup_tar.c.

References lclTocEntry::filename, _tocEntry::formatData, free, NULL, pg_malloc0(), ReadStr(), and lclTocEntry::TH.

Referenced by InitArchiveFmt_Tar().

295 {
296  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
297 
298  if (ctx == NULL)
299  {
300  ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
301  te->formatData = (void *) ctx;
302  }
303 
304  ctx->filename = ReadStr(AH);
305  if (strlen(ctx->filename) == 0)
306  {
307  free(ctx->filename);
308  ctx->filename = NULL;
309  }
310  ctx->TH = NULL;
311 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
char * ReadStr(ArchiveHandle *AH)
TAR_MEMBER * TH
Definition: pg_backup_tar.c:97
static size_t _scriptOut ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 910 of file pg_backup_tar.c.

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

Referenced by _CloseArchive().

911 {
912  lclContext *ctx = (lclContext *) AH->formatData;
913 
914  return tarWrite(buf, len, ctx->scriptTH);
915 }
TAR_MEMBER * scriptTH
Definition: pg_backup_tar.c:92
static char * buf
Definition: pg_test_fsync.c:65
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
static void _StartBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 949 of file pg_backup_tar.c.

References lclContext::blobToc, _archiveHandle::compression, exit_horribly(), _archiveHandle::formatData, _tocEntry::formatData, modulename, tarOpen(), and tarPrintf().

Referenced by InitArchiveFmt_Tar().

950 {
951  lclContext *ctx = (lclContext *) AH->formatData;
952  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
953  char fname[255];
954  char *sfx;
955 
956  if (oid == 0)
957  exit_horribly(modulename, "invalid OID for large object (%u)\n", oid);
958 
959  if (AH->compression != 0)
960  sfx = ".gz";
961  else
962  sfx = "";
963 
964  sprintf(fname, "blob_%u.dat%s", oid, sfx);
965 
966  tarPrintf(AH, ctx->blobToc, "%u %s\n", oid, fname);
967 
968  tctx->TH = tarOpen(AH, fname, 'w');
969 }
static int tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) pg_attribute_printf(3
TAR_MEMBER * blobToc
Definition: pg_backup_tar.c:86
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
static const char * modulename
void exit_horribly(const char *modulename, const char *fmt,...)
static void _StartBlobs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 932 of file pg_backup_tar.c.

References lclContext::blobToc, _archiveHandle::formatData, K_STD_BUF_SIZE, and tarOpen().

Referenced by InitArchiveFmt_Tar().

933 {
934  lclContext *ctx = (lclContext *) AH->formatData;
935  char fname[K_STD_BUF_SIZE];
936 
937  sprintf(fname, "blobs.toc");
938  ctx->blobToc = tarOpen(AH, fname, 'w');
939 }
TAR_MEMBER * blobToc
Definition: pg_backup_tar.c:86
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
#define K_STD_BUF_SIZE
Definition: pg_backup_tar.c:62
static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 323 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

324 {
325  lclTocEntry *tctx = (lclTocEntry *) te->formatData;
326 
327  tctx->TH = tarOpen(AH, tctx->filename, 'w');
328 }
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
TAR_MEMBER * TH
Definition: pg_backup_tar.c:97
static void _tarAddFile ( ArchiveHandle AH,
TAR_MEMBER th 
)
static

Definition at line 1068 of file pg_backup_tar.c.

References _tarWriteHeader(), exit_horribly(), TAR_MEMBER::fileLen, _archiveHandle::formatData, fseeko, ftello, i, INT64_FORMAT, modulename, pgoff_t, READ_ERROR_EXIT, snprintf(), strerror(), TAR_MEMBER::tarFH, lclContext::tarFHpos, TAR_MEMBER::tmpFH, and WRITE_ERROR_EXIT.

Referenced by tarClose().

1069 {
1070  lclContext *ctx = (lclContext *) AH->formatData;
1071  FILE *tmp = th->tmpFH; /* Grab it for convenience */
1072  char buf[32768];
1073  size_t cnt;
1074  pgoff_t len = 0;
1075  size_t res;
1076  size_t i,
1077  pad;
1078 
1079  /*
1080  * Find file len & go back to start.
1081  */
1082  fseeko(tmp, 0, SEEK_END);
1083  th->fileLen = ftello(tmp);
1084  if (th->fileLen < 0)
1085  exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
1086  strerror(errno));
1087  fseeko(tmp, 0, SEEK_SET);
1088 
1089  _tarWriteHeader(th);
1090 
1091  while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
1092  {
1093  if ((res = fwrite(buf, 1, cnt, th->tarFH)) != cnt)
1095  len += res;
1096  }
1097  if (!feof(tmp))
1098  READ_ERROR_EXIT(tmp);
1099 
1100  if (fclose(tmp) != 0) /* This *should* delete it... */
1101  exit_horribly(modulename, "could not close temporary file: %s\n",
1102  strerror(errno));
1103 
1104  if (len != th->fileLen)
1105  {
1106  char buf1[32],
1107  buf2[32];
1108 
1109  snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) len);
1110  snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) th->fileLen);
1111  exit_horribly(modulename, "actual file length (%s) does not match expected (%s)\n",
1112  buf1, buf2);
1113  }
1114 
1115  pad = ((len + 511) & ~511) - len;
1116  for (i = 0; i < pad; i++)
1117  {
1118  if (fputc('\0', th->tarFH) == EOF)
1120  }
1121 
1122  ctx->tarFHpos += len + pad;
1123 }
pgoff_t tarFHpos
Definition: pg_backup_tar.c:88
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define fseeko(stream, offset, origin)
Definition: win32.h:247
static char * buf
Definition: pg_test_fsync.c:65
#define pgoff_t
Definition: win32.h:241
static const char * modulename
static void _tarWriteHeader(TAR_MEMBER *th)
FILE * tmpFH
Definition: pg_backup_tar.c:74
pgoff_t fileLen
Definition: pg_backup_tar.c:78
#define ftello(stream)
Definition: win32.h:250
#define INT64_FORMAT
Definition: c.h:312
#define WRITE_ERROR_EXIT
void exit_horribly(const char *modulename, const char *fmt,...)
int i
const char * strerror(int errnum)
Definition: strerror.c:19
#define READ_ERROR_EXIT(fd)
FILE * tarFH
Definition: pg_backup_tar.c:73
static int _tarGetHeader ( ArchiveHandle AH,
TAR_MEMBER th 
)
static

Definition at line 1209 of file pg_backup_tar.c.

References _tarReadRaw(), ahlog(), exit_horribly(), TAR_MEMBER::fileLen, _archiveHandle::formatData, ftello, i, modulename, ngettext, NULL, pg_strdup(), pgoff_t, read_tar_number(), snprintf(), strlcpy(), tarChecksum(), lclContext::tarFH, lclContext::tarFHpos, TAR_MEMBER::targetFile, and UINT64_FORMAT.

Referenced by _tarPositionTo().

1210 {
1211  lclContext *ctx = (lclContext *) AH->formatData;
1212  char h[512];
1213  char tag[100 + 1];
1214  int sum,
1215  chk;
1216  pgoff_t len;
1217  pgoff_t hPos;
1218  bool gotBlock = false;
1219 
1220  while (!gotBlock)
1221  {
1222  /* Save the pos for reporting purposes */
1223  hPos = ctx->tarFHpos;
1224 
1225  /* Read a 512 byte block, return EOF, exit if short */
1226  len = _tarReadRaw(AH, h, 512, NULL, ctx->tarFH);
1227  if (len == 0) /* EOF */
1228  return 0;
1229 
1230  if (len != 512)
1232  ngettext("incomplete tar header found (%lu byte)\n",
1233  "incomplete tar header found (%lu bytes)\n",
1234  len),
1235  (unsigned long) len);
1236 
1237  /* Calc checksum */
1238  chk = tarChecksum(h);
1239  sum = read_tar_number(&h[148], 8);
1240 
1241  /*
1242  * If the checksum failed, see if it is a null block. If so, silently
1243  * continue to the next block.
1244  */
1245  if (chk == sum)
1246  gotBlock = true;
1247  else
1248  {
1249  int i;
1250 
1251  for (i = 0; i < 512; i++)
1252  {
1253  if (h[i] != 0)
1254  {
1255  gotBlock = true;
1256  break;
1257  }
1258  }
1259  }
1260  }
1261 
1262  /* Name field is 100 bytes, might not be null-terminated */
1263  strlcpy(tag, &h[0], 100 + 1);
1264 
1265  len = read_tar_number(&h[124], 12);
1266 
1267  {
1268  char posbuf[32];
1269  char lenbuf[32];
1270 
1271  snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT, (uint64) hPos);
1272  snprintf(lenbuf, sizeof(lenbuf), UINT64_FORMAT, (uint64) len);
1273  ahlog(AH, 3, "TOC Entry %s at %s (length %s, checksum %d)\n",
1274  tag, posbuf, lenbuf, sum);
1275  }
1276 
1277  if (chk != sum)
1278  {
1279  char posbuf[32];
1280 
1281  snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT,
1282  (uint64) ftello(ctx->tarFH));
1284  "corrupt tar header found in %s "
1285  "(expected %d, computed %d) file position %s\n",
1286  tag, sum, chk, posbuf);
1287  }
1288 
1289  th->targetFile = pg_strdup(tag);
1290  th->fileLen = len;
1291 
1292  return 1;
1293 }
uint64 read_tar_number(const char *s, int len)
Definition: tar.c:56
pgoff_t tarFHpos
Definition: pg_backup_tar.c:88
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
FILE * tarFH
Definition: pg_backup_tar.c:87
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define pgoff_t
Definition: win32.h:241
#define ngettext(s, p, n)
Definition: c.h:127
static const char * modulename
int tarChecksum(char *header)
Definition: tar.c:88
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
pgoff_t fileLen
Definition: pg_backup_tar.c:78
#define ftello(stream)
Definition: win32.h:250
void exit_horribly(const char *modulename, const char *fmt,...)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
#define UINT64_FORMAT
Definition: c.h:313
char * targetFile
Definition: pg_backup_tar.c:75
static size_t _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
static TAR_MEMBER * _tarPositionTo ( ArchiveHandle AH,
const char *  filename 
)
static

Definition at line 1127 of file pg_backup_tar.c.

References _tarGetHeader(), _tarReadRaw(), TAR_MEMBER::AH, ahlog(), exit_horribly(), TAR_MEMBER::fileLen, _archiveHandle::formatData, free, header(), i, INT64_FORMAT, modulename, NULL, pg_malloc0(), TAR_MEMBER::pos, REQ_DATA, snprintf(), lclContext::tarFH, lclContext::tarFHpos, TAR_MEMBER::targetFile, lclContext::tarNextMember, and TocIDRequired().

Referenced by tarOpen().

1128 {
1129  lclContext *ctx = (lclContext *) AH->formatData;
1130  TAR_MEMBER *th = pg_malloc0(sizeof(TAR_MEMBER));
1131  char c;
1132  char header[512];
1133  size_t i,
1134  len,
1135  blks;
1136  int id;
1137 
1138  th->AH = AH;
1139 
1140  /* Go to end of current file, if any */
1141  if (ctx->tarFHpos != 0)
1142  {
1143  char buf1[100],
1144  buf2[100];
1145 
1146  snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ctx->tarFHpos);
1147  snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) ctx->tarNextMember);
1148  ahlog(AH, 4, "moving from position %s to next member at file position %s\n",
1149  buf1, buf2);
1150 
1151  while (ctx->tarFHpos < ctx->tarNextMember)
1152  _tarReadRaw(AH, &c, 1, NULL, ctx->tarFH);
1153  }
1154 
1155  {
1156  char buf[100];
1157 
1158  snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ctx->tarFHpos);
1159  ahlog(AH, 4, "now at file position %s\n", buf);
1160  }
1161 
1162  /* We are at the start of the file, or at the next member */
1163 
1164  /* Get the header */
1165  if (!_tarGetHeader(AH, th))
1166  {
1167  if (filename)
1168  exit_horribly(modulename, "could not find header for file \"%s\" in tar archive\n", filename);
1169  else
1170  {
1171  /*
1172  * We're just scanning the archive for the next file, so return
1173  * null
1174  */
1175  free(th);
1176  return NULL;
1177  }
1178  }
1179 
1180  while (filename != NULL && strcmp(th->targetFile, filename) != 0)
1181  {
1182  ahlog(AH, 4, "skipping tar member %s\n", th->targetFile);
1183 
1184  id = atoi(th->targetFile);
1185  if ((TocIDRequired(AH, id) & REQ_DATA) != 0)
1186  exit_horribly(modulename, "restoring data out of order is not supported in this archive format: "
1187  "\"%s\" is required, but comes before \"%s\" in the archive file.\n",
1188  th->targetFile, filename);
1189 
1190  /* Header doesn't match, so read to next header */
1191  len = ((th->fileLen + 511) & ~511); /* Padded length */
1192  blks = len >> 9; /* # of 512 byte blocks */
1193 
1194  for (i = 0; i < blks; i++)
1195  _tarReadRaw(AH, &header[0], 512, NULL, ctx->tarFH);
1196 
1197  if (!_tarGetHeader(AH, th))
1198  exit_horribly(modulename, "could not find header for file \"%s\" in tar archive\n", filename);
1199  }
1200 
1201  ctx->tarNextMember = ctx->tarFHpos + ((th->fileLen + 511) & ~511);
1202  th->pos = 0;
1203 
1204  return th;
1205 }
pgoff_t tarFHpos
Definition: pg_backup_tar.c:88
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
pgoff_t tarNextMember
Definition: pg_backup_tar.c:89
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
FILE * tarFH
Definition: pg_backup_tar.c:87
char * c
static char * buf
Definition: pg_test_fsync.c:65
static const char * modulename
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
teReqs TocIDRequired(ArchiveHandle *AH, DumpId id)
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:205
#define INT64_FORMAT
Definition: c.h:312
void exit_horribly(const char *modulename, const char *fmt,...)
static char * filename
Definition: pg_dumpall.c:84
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
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 _tarReadRaw ( ArchiveHandle AH,
void *  buf,
size_t  len,
TAR_MEMBER th,
FILE *  fh 
)
static

Definition at line 518 of file pg_backup_tar.c.

References exit_horribly(), _archiveHandle::formatData, GZEOF, GZREAD, _archiveHandle::lookahead, _archiveHandle::lookaheadLen, _archiveHandle::lookaheadPos, modulename, TAR_MEMBER::nFH, READ_ERROR_EXIT, strerror(), lclContext::tarFHpos, and TAR_MEMBER::zFH.

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

519 {
520  lclContext *ctx = (lclContext *) AH->formatData;
521  size_t avail;
522  size_t used = 0;
523  size_t res = 0;
524 
525  avail = AH->lookaheadLen - AH->lookaheadPos;
526  if (avail > 0)
527  {
528  /* We have some lookahead bytes to use */
529  if (avail >= len) /* Just use the lookahead buffer */
530  used = len;
531  else
532  used = avail;
533 
534  /* Copy, and adjust buffer pos */
535  memcpy(buf, AH->lookahead + AH->lookaheadPos, used);
536  AH->lookaheadPos += used;
537 
538  /* Adjust required length */
539  len -= used;
540  }
541 
542  /* Read the file if len > 0 */
543  if (len > 0)
544  {
545  if (fh)
546  {
547  res = fread(&((char *) buf)[used], 1, len, fh);
548  if (res != len && !feof(fh))
549  READ_ERROR_EXIT(fh);
550  }
551  else if (th)
552  {
553  if (th->zFH)
554  {
555  res = GZREAD(&((char *) buf)[used], 1, len, th->zFH);
556  if (res != len && !GZEOF(th->zFH))
558  "could not read from input file: %s\n", strerror(errno));
559  }
560  else
561  {
562  res = fread(&((char *) buf)[used], 1, len, th->nFH);
563  if (res != len && !feof(th->nFH))
564  READ_ERROR_EXIT(th->nFH);
565  }
566  }
567  else
568  exit_horribly(modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n");
569  }
570 
571  ctx->tarFHpos += res + used;
572 
573  return (res + used);
574 }
FILE * zFH
Definition: pg_backup_tar.c:70
pgoff_t tarFHpos
Definition: pg_backup_tar.c:88
static char * buf
Definition: pg_test_fsync.c:65
#define GZEOF(fh)
FILE * nFH
Definition: pg_backup_tar.c:72
static const char * modulename
#define GZREAD(p, s, n, fh)
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
#define READ_ERROR_EXIT(fd)
static void _tarWriteHeader ( TAR_MEMBER th)
static

Definition at line 1297 of file pg_backup_tar.c.

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

Referenced by _tarAddFile().

1298 {
1299  char h[512];
1300 
1301  tarCreateHeader(h, th->targetFile, NULL, th->fileLen,
1302  0600, 04000, 02000, time(NULL));
1303 
1304  /* Now write the completed header. */
1305  if (fwrite(h, 1, 512, th->tarFH) != 512)
1307 }
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:112
#define NULL
Definition: c.h:226
pgoff_t fileLen
Definition: pg_backup_tar.c:78
#define WRITE_ERROR_EXIT
FILE * tarFH
Definition: pg_backup_tar.c:73
char * targetFile
Definition: pg_backup_tar.c:75
static void _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 800 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

801 {
802  lclContext *ctx = (lclContext *) AH->formatData;
803 
804  if (tarWrite(buf, len, ctx->FH) != len)
806 
807  ctx->filePos += len;
808 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
static char * buf
Definition: pg_test_fsync.c:65
#define WRITE_ERROR_EXIT
pgoff_t filePos
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
static int _WriteByte ( ArchiveHandle AH,
const int  i 
)
static

Definition at line 771 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

772 {
773  lclContext *ctx = (lclContext *) AH->formatData;
774  char b = i; /* Avoid endian problems */
775 
776  if (tarWrite(&b, 1, ctx->FH) != 1)
778 
779  ctx->filePos += 1;
780  return 1;
781 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
#define WRITE_ERROR_EXIT
int i
pgoff_t filePos
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
static void _WriteData ( ArchiveHandle AH,
const void *  data,
size_t  dLen 
)
static

Definition at line 609 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

610 {
611  lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData;
612 
613  if (tarWrite(data, dLen, tctx->TH) != dLen)
615 
616  return;
617 }
struct _tocEntry * currToc
#define WRITE_ERROR_EXIT
TAR_MEMBER * TH
Definition: pg_backup_tar.c:97
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 283 of file pg_backup_tar.c.

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

Referenced by InitArchiveFmt_Tar().

284 {
285  lclTocEntry *ctx = (lclTocEntry *) te->formatData;
286 
287  if (ctx->filename)
288  WriteStr(AH, ctx->filename);
289  else
290  WriteStr(AH, "");
291 }
size_t WriteStr(ArchiveHandle *AH, const char *c)
void InitArchiveFmt_Tar ( ArchiveHandle AH)

Definition at line 128 of file pg_backup_tar.c.

References _ArchiveEntry(), _CloseArchive(), _EndBlob(), _EndBlobs(), _EndData(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _StartBlob(), _StartBlobs(), _StartData(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), archModeWrite, checkSeek(), exit_horribly(), lclContext::FH, lclContext::filePos, lclContext::hasSeek, lclContext::isSpecialScript, LOBBUFSIZE, modulename, NULL, PG_BINARY_R, PG_BINARY_W, pg_malloc(), pg_malloc0(), ReadHead(), ReadToc(), strerror(), tarClose(), lclContext::tarFH, lclContext::tarFHpos, and tarOpen().

Referenced by _allocAH().

129 {
130  lclContext *ctx;
131 
132  /* Assuming static functions, this can be copied for each format. */
134  AH->StartDataPtr = _StartData;
135  AH->WriteDataPtr = _WriteData;
136  AH->EndDataPtr = _EndData;
137  AH->WriteBytePtr = _WriteByte;
138  AH->ReadBytePtr = _ReadByte;
139  AH->WriteBufPtr = _WriteBuf;
140  AH->ReadBufPtr = _ReadBuf;
141  AH->ClosePtr = _CloseArchive;
142  AH->ReopenPtr = NULL;
147 
149  AH->StartBlobPtr = _StartBlob;
150  AH->EndBlobPtr = _EndBlob;
151  AH->EndBlobsPtr = _EndBlobs;
152  AH->ClonePtr = NULL;
153  AH->DeClonePtr = NULL;
154 
155  AH->WorkerJobDumpPtr = NULL;
157 
158  /*
159  * Set up some special context used in compressing data.
160  */
161  ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
162  AH->formatData = (void *) ctx;
163  ctx->filePos = 0;
164  ctx->isSpecialScript = 0;
165 
166  /* Initialize LO buffering */
167  AH->lo_buf_size = LOBBUFSIZE;
168  AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
169 
170  /*
171  * Now open the tar file, and load the TOC if we're in read mode.
172  */
173  if (AH->mode == archModeWrite)
174  {
175  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
176  {
177  ctx->tarFH = fopen(AH->fSpec, PG_BINARY_W);
178  if (ctx->tarFH == NULL)
180  "could not open TOC file \"%s\" for output: %s\n",
181  AH->fSpec, strerror(errno));
182  }
183  else
184  {
185  ctx->tarFH = stdout;
186  if (ctx->tarFH == NULL)
188  "could not open TOC file for output: %s\n",
189  strerror(errno));
190  }
191 
192  ctx->tarFHpos = 0;
193 
194  /*
195  * Make unbuffered since we will dup() it, and the buffers screw each
196  * other
197  */
198  /* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
199 
200  ctx->hasSeek = checkSeek(ctx->tarFH);
201 
202  /*
203  * We don't support compression because reading the files back is not
204  * possible since gzdopen uses buffered IO which totally screws file
205  * positioning.
206  */
207  if (AH->compression != 0)
209  "compression is not supported by tar archive format\n");
210  }
211  else
212  { /* Read Mode */
213  if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
214  {
215  ctx->tarFH = fopen(AH->fSpec, PG_BINARY_R);
216  if (ctx->tarFH == NULL)
217  exit_horribly(modulename, "could not open TOC file \"%s\" for input: %s\n",
218  AH->fSpec, strerror(errno));
219  }
220  else
221  {
222  ctx->tarFH = stdin;
223  if (ctx->tarFH == NULL)
224  exit_horribly(modulename, "could not open TOC file for input: %s\n",
225  strerror(errno));
226  }
227 
228  /*
229  * Make unbuffered since we will dup() it, and the buffers screw each
230  * other
231  */
232  /* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
233 
234  ctx->tarFHpos = 0;
235 
236  ctx->hasSeek = checkSeek(ctx->tarFH);
237 
238  /*
239  * Forcibly unmark the header as read since we use the lookahead
240  * buffer
241  */
242  AH->readHeader = 0;
243 
244  ctx->FH = (void *) tarOpen(AH, "toc.dat", 'r');
245  ReadHead(AH);
246  ReadToc(AH);
247  tarClose(AH, ctx->FH); /* Nothing else in the file... */
248  }
249 }
TAR_MEMBER * FH
Definition: pg_backup_tar.c:90
void ReadToc(ArchiveHandle *AH)
static void _StartData(ArchiveHandle *AH, TocEntry *te)
StartBlobsPtr StartBlobsPtr
void ReadHead(ArchiveHandle *AH)
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static TAR_MEMBER * tarOpen(ArchiveHandle *AH, const char *filename, char mode)
PrintTocDataPtr PrintTocDataPtr
pgoff_t tarFHpos
Definition: pg_backup_tar.c:88
WorkerJobDumpPtr WorkerJobDumpPtr
WriteBufPtr WriteBufPtr
WriteExtraTocPtr WriteExtraTocPtr
#define PG_BINARY_W
Definition: c.h:1041
static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
#define PG_BINARY_R
Definition: c.h:1040
int isSpecialScript
Definition: pg_backup_tar.c:91
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
PrintExtraTocPtr PrintExtraTocPtr
FILE * tarFH
Definition: pg_backup_tar.c:87
WriteBytePtr WriteBytePtr
static void _StartBlobs(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
WorkerJobRestorePtr WorkerJobRestorePtr
ArchiveEntryPtr ArchiveEntryPtr
ReadBytePtr ReadBytePtr
static void tarClose(ArchiveHandle *AH, TAR_MEMBER *TH)
static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndBlobs(ArchiveHandle *AH, TocEntry *te)
static const char * modulename
#define NULL
Definition: c.h:226
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
WriteDataPtr WriteDataPtr
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
void exit_horribly(const char *modulename, const char *fmt,...)
StartDataPtr StartDataPtr
static void _CloseArchive(ArchiveHandle *AH)
EndBlobsPtr EndBlobsPtr
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
const char * strerror(int errnum)
Definition: strerror.c:19
bool checkSeek(FILE *fp)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
pgoff_t filePos
static int _ReadByte(ArchiveHandle *)
ReadExtraTocPtr ReadExtraTocPtr
#define LOBBUFSIZE
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
StartBlobPtr StartBlobPtr
bool isValidTarHeader ( char *  header)

Definition at line 1042 of file pg_backup_tar.c.

References read_tar_number(), and tarChecksum().

Referenced by _discoverArchiveFormat().

1043 {
1044  int sum;
1045  int chk = tarChecksum(header);
1046 
1047  sum = read_tar_number(&header[148], 8);
1048 
1049  if (sum != chk)
1050  return false;
1051 
1052  /* POSIX tar format */
1053  if (memcmp(&header[257], "ustar\0", 6) == 0 &&
1054  memcmp(&header[263], "00", 2) == 0)
1055  return true;
1056  /* GNU tar format */
1057  if (memcmp(&header[257], "ustar \0", 8) == 0)
1058  return true;
1059  /* not-quite-POSIX format written by pre-9.3 pg_dump */
1060  if (memcmp(&header[257], "ustar00\0", 8) == 0)
1061  return true;
1062 
1063  return false;
1064 }
uint64 read_tar_number(const char *s, int len)
Definition: tar.c:56
int tarChecksum(char *header)
Definition: tar.c:88
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:205
static void tarClose ( ArchiveHandle AH,
TAR_MEMBER TH 
)
static

Definition at line 448 of file pg_backup_tar.c.

References _tarAddFile(), _archiveHandle::compression, exit_horribly(), free, GZCLOSE, TAR_MEMBER::mode, modulename, TAR_MEMBER::nFH, NULL, TAR_MEMBER::targetFile, and TAR_MEMBER::zFH.

Referenced by _CloseArchive(), _EndBlob(), _EndBlobs(), _EndData(), _LoadBlobs(), _PrintFileData(), and InitArchiveFmt_Tar().

449 {
450  /*
451  * Close the GZ file since we dup'd. This will flush the buffers.
452  */
453  if (AH->compression != 0)
454  if (GZCLOSE(th->zFH) != 0)
455  exit_horribly(modulename, "could not close tar member\n");
456 
457  if (th->mode == 'w')
458  _tarAddFile(AH, th); /* This will close the temp file */
459 
460  /*
461  * else Nothing to do for normal read since we don't dup() normal file
462  * handle, and we don't use temp files.
463  */
464 
465  if (th->targetFile)
466  free(th->targetFile);
467 
468  th->nFH = NULL;
469  th->zFH = NULL;
470 }
static const char * modulename
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
#define GZCLOSE(fh)
static int static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
void exit_horribly(const char *modulename, const char *fmt,...)
static TAR_MEMBER * tarOpen ( ArchiveHandle AH,
const char *  filename,
char  mode 
)
static

Definition at line 331 of file pg_backup_tar.c.

References _tarPositionTo(), _archiveHandle::compression, exit_horribly(), fd(), _archiveHandle::formatData, free, modulename, name, NULL, pg_malloc0(), pg_strdup(), S_IRWXG, S_IRWXO, strerror(), lclContext::tarFH, and tm.

Referenced by _CloseArchive(), _LoadBlobs(), _PrintFileData(), _StartBlob(), _StartBlobs(), _StartData(), and InitArchiveFmt_Tar().

332 {
333  lclContext *ctx = (lclContext *) AH->formatData;
334  TAR_MEMBER *tm;
335 
336 #ifdef HAVE_LIBZ
337  char fmode[10];
338 #endif
339 
340  if (mode == 'r')
341  {
342  tm = _tarPositionTo(AH, filename);
343  if (!tm) /* Not found */
344  {
345  if (filename)
346  {
347  /*
348  * Couldn't find the requested file. Future: do SEEK(0) and
349  * retry.
350  */
351  exit_horribly(modulename, "could not find file \"%s\" in archive\n", filename);
352  }
353  else
354  {
355  /* Any file OK, none left, so return NULL */
356  return NULL;
357  }
358  }
359 
360 #ifdef HAVE_LIBZ
361 
362  if (AH->compression == 0)
363  tm->nFH = ctx->tarFH;
364  else
365  exit_horribly(modulename, "compression is not supported by tar archive format\n");
366  /* tm->zFH = gzdopen(dup(fileno(ctx->tarFH)), "rb"); */
367 #else
368  tm->nFH = ctx->tarFH;
369 #endif
370  }
371  else
372  {
373  int old_umask;
374 
375  tm = pg_malloc0(sizeof(TAR_MEMBER));
376 
377  /*
378  * POSIX does not require, but permits, tmpfile() to restrict file
379  * permissions. Given an OS crash after we write data, the filesystem
380  * might retain the data but forget tmpfile()'s unlink(). If so, the
381  * file mode protects confidentiality of the data written.
382  */
383  old_umask = umask(S_IRWXG | S_IRWXO);
384 
385 #ifndef WIN32
386  tm->tmpFH = tmpfile();
387 #else
388 
389  /*
390  * On WIN32, tmpfile() generates a filename in the root directory,
391  * which requires administrative permissions on certain systems. Loop
392  * until we find a unique file name we can create.
393  */
394  while (1)
395  {
396  char *name;
397  int fd;
398 
399  name = _tempnam(NULL, "pg_temp_");
400  if (name == NULL)
401  break;
402  fd = open(name, O_RDWR | O_CREAT | O_EXCL | O_BINARY |
403  O_TEMPORARY, S_IRUSR | S_IWUSR);
404  free(name);
405 
406  if (fd != -1) /* created a file */
407  {
408  tm->tmpFH = fdopen(fd, "w+b");
409  break;
410  }
411  else if (errno != EEXIST) /* failure other than file exists */
412  break;
413  }
414 #endif
415 
416  if (tm->tmpFH == NULL)
417  exit_horribly(modulename, "could not generate temporary file name: %s\n", strerror(errno));
418 
419  umask(old_umask);
420 
421 #ifdef HAVE_LIBZ
422 
423  if (AH->compression != 0)
424  {
425  sprintf(fmode, "wb%d", AH->compression);
426  tm->zFH = gzdopen(dup(fileno(tm->tmpFH)), fmode);
427  if (tm->zFH == NULL)
428  exit_horribly(modulename, "could not open temporary file\n");
429  }
430  else
431  tm->nFH = tm->tmpFH;
432 #else
433 
434  tm->nFH = tm->tmpFH;
435 #endif
436 
437  tm->AH = AH;
438  tm->targetFile = pg_strdup(filename);
439  }
440 
441  tm->mode = mode;
442  tm->tarFH = ctx->tarFH;
443 
444  return tm;
445 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static struct pg_tm tm
Definition: localtime.c:103
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
FILE * tarFH
Definition: pg_backup_tar.c:87
static TAR_MEMBER * _tarPositionTo(ArchiveHandle *AH, const char *filename)
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static const char * modulename
#define S_IRWXO
Definition: win32.h:484
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
const char * name
Definition: encode.c:521
void exit_horribly(const char *modulename, const char *fmt,...)
#define S_IRWXG
Definition: win32.h:480
static char * filename
Definition: pg_dumpall.c:84
const char * strerror(int errnum)
Definition: strerror.c:19
static int tarPrintf ( ArchiveHandle AH,
TAR_MEMBER th,
const char *  fmt,
  ... 
)
static

Definition at line 1010 of file pg_backup_tar.c.

References generate_unaccent_rules::args, free, pg_malloc(), pvsnprintf(), and tarWrite().

Referenced by _CloseArchive(), and _StartBlob().

1011 {
1012  char *p;
1013  size_t len = 128; /* initial assumption about buffer size */
1014  size_t cnt;
1015 
1016  for (;;)
1017  {
1018  va_list args;
1019 
1020  /* Allocate work buffer. */
1021  p = (char *) pg_malloc(len);
1022 
1023  /* Try to format the data. */
1024  va_start(args, fmt);
1025  cnt = pvsnprintf(p, len, fmt, args);
1026  va_end(args);
1027 
1028  if (cnt < len)
1029  break; /* success */
1030 
1031  /* Release buffer and loop around to try again with larger len. */
1032  free(p);
1033  len = cnt;
1034  }
1035 
1036  cnt = tarWrite(p, cnt, th);
1037  free(p);
1038  return (int) cnt;
1039 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:104
#define free(a)
Definition: header.h:60
static size_t tarWrite(const void *buf, size_t len, TAR_MEMBER *th)
static size_t tarRead ( void *  buf,
size_t  len,
TAR_MEMBER th 
)
static

Definition at line 577 of file pg_backup_tar.c.

References _tarReadRaw(), TAR_MEMBER::AH, TAR_MEMBER::fileLen, NULL, and TAR_MEMBER::pos.

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

578 {
579  size_t res;
580 
581  if (th->pos + len > th->fileLen)
582  len = th->fileLen - th->pos;
583 
584  if (len <= 0)
585  return 0;
586 
587  res = _tarReadRaw(th->AH, buf, len, th, NULL);
588 
589  th->pos += res;
590 
591  return res;
592 }
ArchiveHandle * AH
Definition: pg_backup_tar.c:79
static char * buf
Definition: pg_test_fsync.c:65
pgoff_t pos
Definition: pg_backup_tar.c:77
#define NULL
Definition: c.h:226
pgoff_t fileLen
Definition: pg_backup_tar.c:78
static size_t _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
static size_t tarWrite ( const void *  buf,
size_t  len,
TAR_MEMBER th 
)
static

Definition at line 595 of file pg_backup_tar.c.

References GZWRITE, TAR_MEMBER::nFH, NULL, TAR_MEMBER::pos, and TAR_MEMBER::zFH.

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

596 {
597  size_t res;
598 
599  if (th->zFH != NULL)
600  res = GZWRITE(buf, 1, len, th->zFH);
601  else
602  res = fwrite(buf, 1, len, th->nFH);
603 
604  th->pos += res;
605  return res;
606 }
FILE * zFH
Definition: pg_backup_tar.c:70
static char * buf
Definition: pg_test_fsync.c:65
#define GZWRITE(p, s, n, fh)
FILE * nFH
Definition: pg_backup_tar.c:72
pgoff_t pos
Definition: pg_backup_tar.c:77
#define NULL
Definition: c.h:226

Variable Documentation

const char* modulename = gettext_noop("tar archiver")
static