Commit 3c0afde1 authored by Bruce Momjian's avatar Bruce Momjian

Modify pg_dump to use error-free memory allocation macros. This avoids

ignoring errors and call-site error checking.
parent 35e27226
...@@ -20,7 +20,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) ...@@ -20,7 +20,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \ OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
pg_backup_files.o pg_backup_null.o pg_backup_tar.o \ pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
pg_backup_directory.o dumputils.o compress_io.o $(WIN32RES) pg_backup_directory.o common.o dumputils.o compress_io.o $(WIN32RES)
KEYWRDOBJS = keywords.o kwlookup.o KEYWRDOBJS = keywords.o kwlookup.o
...@@ -29,8 +29,8 @@ kwlookup.c: % : $(top_srcdir)/src/backend/parser/% ...@@ -29,8 +29,8 @@ kwlookup.c: % : $(top_srcdir)/src/backend/parser/%
all: pg_dump pg_restore pg_dumpall all: pg_dump pg_restore pg_dumpall
pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport pg_dump: pg_dump.o dumpcatalog.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
$(CC) $(CFLAGS) pg_dump.o common.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) $(CC) $(CFLAGS) pg_dump.o dumpcatalog.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
$(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) $(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
...@@ -50,4 +50,4 @@ uninstall: ...@@ -50,4 +50,4 @@ uninstall:
rm -f $(addprefix '$(DESTDIR)$(bindir)'/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X)) rm -f $(addprefix '$(DESTDIR)$(bindir)'/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))
clean distclean maintainer-clean: clean distclean maintainer-clean:
rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o pg_dumpall.o kwlookup.c $(KEYWRDOBJS) rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o dumpcatalog.o pg_dump_sort.o pg_restore.o pg_dumpall.o kwlookup.c $(KEYWRDOBJS)
This diff is collapsed.
/*-------------------------------------------------------------------------
*
* common.h
* Common header file for the pg_dump, pg_dumpall, and pg_restore
*
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/bin/pg_dump/common.h
*
*-------------------------------------------------------------------------
*/
#ifndef COMMON_H
#define COMMON_H
#include "postgres_fe.h"
extern char *pg_strdup(const char *string);
extern void *pg_malloc(size_t size);
extern void *pg_calloc(size_t nmemb, size_t size);
extern void *pg_realloc(void *ptr, size_t size);
#endif /* COMMON_H */
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
*/ */
#include "compress_io.h" #include "compress_io.h"
#include "common.h"
/*---------------------- /*----------------------
* Compressor API * Compressor API
...@@ -135,9 +136,7 @@ AllocateCompressor(int compression, WriteFunc writeF) ...@@ -135,9 +136,7 @@ AllocateCompressor(int compression, WriteFunc writeF)
die_horribly(NULL, modulename, "not built with zlib support\n"); die_horribly(NULL, modulename, "not built with zlib support\n");
#endif #endif
cs = (CompressorState *) calloc(1, sizeof(CompressorState)); cs = (CompressorState *) pg_calloc(1, sizeof(CompressorState));
if (cs == NULL)
die_horribly(NULL, modulename, "out of memory\n");
cs->writeF = writeF; cs->writeF = writeF;
cs->comprAlg = alg; cs->comprAlg = alg;
...@@ -221,9 +220,7 @@ InitCompressorZlib(CompressorState *cs, int level) ...@@ -221,9 +220,7 @@ InitCompressorZlib(CompressorState *cs, int level)
{ {
z_streamp zp; z_streamp zp;
zp = cs->zp = (z_streamp) malloc(sizeof(z_stream)); zp = cs->zp = (z_streamp) pg_malloc(sizeof(z_stream));
if (cs->zp == NULL)
die_horribly(NULL, modulename, "out of memory\n");
zp->zalloc = Z_NULL; zp->zalloc = Z_NULL;
zp->zfree = Z_NULL; zp->zfree = Z_NULL;
zp->opaque = Z_NULL; zp->opaque = Z_NULL;
...@@ -233,12 +230,9 @@ InitCompressorZlib(CompressorState *cs, int level) ...@@ -233,12 +230,9 @@ InitCompressorZlib(CompressorState *cs, int level)
* actually allocate one extra byte because some routines want to append a * actually allocate one extra byte because some routines want to append a
* trailing zero byte to the zlib output. * trailing zero byte to the zlib output.
*/ */
cs->zlibOut = (char *) malloc(ZLIB_OUT_SIZE + 1); cs->zlibOut = (char *) pg_malloc(ZLIB_OUT_SIZE + 1);
cs->zlibOutSize = ZLIB_OUT_SIZE; cs->zlibOutSize = ZLIB_OUT_SIZE;
if (cs->zlibOut == NULL)
die_horribly(NULL, modulename, "out of memory\n");
if (deflateInit(zp, level) != Z_OK) if (deflateInit(zp, level) != Z_OK)
die_horribly(NULL, modulename, die_horribly(NULL, modulename,
"could not initialize compression library: %s\n", "could not initialize compression library: %s\n",
...@@ -338,21 +332,15 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) ...@@ -338,21 +332,15 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF)
char *buf; char *buf;
size_t buflen; size_t buflen;
zp = (z_streamp) malloc(sizeof(z_stream)); zp = (z_streamp) pg_malloc(sizeof(z_stream));
if (zp == NULL)
die_horribly(NULL, modulename, "out of memory\n");
zp->zalloc = Z_NULL; zp->zalloc = Z_NULL;
zp->zfree = Z_NULL; zp->zfree = Z_NULL;
zp->opaque = Z_NULL; zp->opaque = Z_NULL;
buf = malloc(ZLIB_IN_SIZE); buf = pg_malloc(ZLIB_IN_SIZE);
if (buf == NULL)
die_horribly(NULL, modulename, "out of memory\n");
buflen = ZLIB_IN_SIZE; buflen = ZLIB_IN_SIZE;
out = malloc(ZLIB_OUT_SIZE + 1); out = pg_malloc(ZLIB_OUT_SIZE + 1);
if (out == NULL)
die_horribly(NULL, modulename, "out of memory\n");
if (inflateInit(zp) != Z_OK) if (inflateInit(zp) != Z_OK)
die_horribly(NULL, modulename, die_horribly(NULL, modulename,
...@@ -417,9 +405,7 @@ ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF) ...@@ -417,9 +405,7 @@ ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF)
char *buf; char *buf;
size_t buflen; size_t buflen;
buf = malloc(ZLIB_OUT_SIZE); buf = pg_malloc(ZLIB_OUT_SIZE);
if (buf == NULL)
die_horribly(NULL, modulename, "out of memory\n");
buflen = ZLIB_OUT_SIZE; buflen = ZLIB_OUT_SIZE;
while ((cnt = readF(AH, &buf, &buflen))) while ((cnt = readF(AH, &buf, &buflen)))
...@@ -491,10 +477,7 @@ cfopen_read(const char *path, const char *mode) ...@@ -491,10 +477,7 @@ cfopen_read(const char *path, const char *mode)
if (fp == NULL) if (fp == NULL)
{ {
int fnamelen = strlen(path) + 4; int fnamelen = strlen(path) + 4;
char *fname = malloc(fnamelen); char *fname = pg_malloc(fnamelen);
if (fname == NULL)
die_horribly(NULL, modulename, "Out of memory\n");
snprintf(fname, fnamelen, "%s%s", path, ".gz"); snprintf(fname, fnamelen, "%s%s", path, ".gz");
fp = cfopen(fname, mode, 1); fp = cfopen(fname, mode, 1);
...@@ -525,10 +508,7 @@ cfopen_write(const char *path, const char *mode, int compression) ...@@ -525,10 +508,7 @@ cfopen_write(const char *path, const char *mode, int compression)
{ {
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
int fnamelen = strlen(path) + 4; int fnamelen = strlen(path) + 4;
char *fname = malloc(fnamelen); char *fname = pg_malloc(fnamelen);
if (fname == NULL)
die_horribly(NULL, modulename, "Out of memory\n");
snprintf(fname, fnamelen, "%s%s", path, ".gz"); snprintf(fname, fnamelen, "%s%s", path, ".gz");
fp = cfopen(fname, mode, 1); fp = cfopen(fname, mode, 1);
...@@ -548,10 +528,7 @@ cfopen_write(const char *path, const char *mode, int compression) ...@@ -548,10 +528,7 @@ cfopen_write(const char *path, const char *mode, int compression)
cfp * cfp *
cfopen(const char *path, const char *mode, int compression) cfopen(const char *path, const char *mode, int compression)
{ {
cfp *fp = malloc(sizeof(cfp)); cfp *fp = pg_malloc(sizeof(cfp));
if (fp == NULL)
die_horribly(NULL, modulename, "Out of memory\n");
if (compression != 0) if (compression != 0)
{ {
......
This diff is collapsed.
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <ctype.h> #include <ctype.h>
#include "common.h"
#include "dumputils.h" #include "dumputils.h"
#include "parser/keywords.h" #include "parser/keywords.h"
......
This diff is collapsed.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
*/ */
#include "compress_io.h" #include "compress_io.h"
#include "common.h"
/*-------- /*--------
* Routines in the format interface * Routines in the format interface
...@@ -126,16 +127,12 @@ InitArchiveFmt_Custom(ArchiveHandle *AH) ...@@ -126,16 +127,12 @@ InitArchiveFmt_Custom(ArchiveHandle *AH)
AH->DeClonePtr = _DeClone; AH->DeClonePtr = _DeClone;
/* Set up a private area. */ /* Set up a private area. */
ctx = (lclContext *) calloc(1, sizeof(lclContext)); ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
if (ctx == NULL)
die_horribly(AH, modulename, "out of memory\n");
AH->formatData = (void *) ctx; AH->formatData = (void *) ctx;
/* Initialize LO buffering */ /* Initialize LO buffering */
AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf_size = LOBBUFSIZE;
AH->lo_buf = (void *) malloc(LOBBUFSIZE); AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
if (AH->lo_buf == NULL)
die_horribly(AH, modulename, "out of memory\n");
ctx->filePos = 0; ctx->filePos = 0;
...@@ -199,7 +196,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) ...@@ -199,7 +196,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
{ {
lclTocEntry *ctx; lclTocEntry *ctx;
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
if (te->dataDumper) if (te->dataDumper)
ctx->dataState = K_OFFSET_POS_NOT_SET; ctx->dataState = K_OFFSET_POS_NOT_SET;
else else
...@@ -240,7 +237,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te) ...@@ -240,7 +237,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
if (ctx == NULL) if (ctx == NULL)
{ {
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
te->formatData = (void *) ctx; te->formatData = (void *) ctx;
} }
...@@ -566,7 +563,7 @@ _skipData(ArchiveHandle *AH) ...@@ -566,7 +563,7 @@ _skipData(ArchiveHandle *AH)
{ {
if (buf) if (buf)
free(buf); free(buf);
buf = (char *) malloc(blkLen); buf = (char *) pg_malloc(blkLen);
buflen = blkLen; buflen = blkLen;
} }
cnt = fread(buf, 1, blkLen, AH->FH); cnt = fread(buf, 1, blkLen, AH->FH);
...@@ -774,9 +771,7 @@ _Clone(ArchiveHandle *AH) ...@@ -774,9 +771,7 @@ _Clone(ArchiveHandle *AH)
{ {
lclContext *ctx = (lclContext *) AH->formatData; lclContext *ctx = (lclContext *) AH->formatData;
AH->formatData = (lclContext *) malloc(sizeof(lclContext)); AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
if (AH->formatData == NULL)
die_horribly(AH, modulename, "out of memory\n");
memcpy(AH->formatData, ctx, sizeof(lclContext)); memcpy(AH->formatData, ctx, sizeof(lclContext));
ctx = (lclContext *) AH->formatData; ctx = (lclContext *) AH->formatData;
...@@ -901,9 +896,7 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen) ...@@ -901,9 +896,7 @@ _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
if (blkLen > *buflen) if (blkLen > *buflen)
{ {
free(*buf); free(*buf);
*buf = (char *) malloc(blkLen); *buf = (char *) pg_malloc(blkLen);
if (!(*buf))
die_horribly(AH, modulename, "out of memory\n");
*buflen = blkLen; *buflen = blkLen;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
*/ */
#include "pg_backup_db.h" #include "pg_backup_db.h"
#include "common.h"
#include "dumputils.h" #include "dumputils.h"
#include <unistd.h> #include <unistd.h>
...@@ -55,7 +56,7 @@ _check_database_version(ArchiveHandle *AH) ...@@ -55,7 +56,7 @@ _check_database_version(ArchiveHandle *AH)
remoteversion = _parse_version(AH, remoteversion_str); remoteversion = _parse_version(AH, remoteversion_str);
AH->public.remoteVersionStr = strdup(remoteversion_str); AH->public.remoteVersionStr = pg_strdup(remoteversion_str);
AH->public.remoteVersion = remoteversion; AH->public.remoteVersion = remoteversion;
if (!AH->archiveRemoteVersion) if (!AH->archiveRemoteVersion)
AH->archiveRemoteVersion = AH->public.remoteVersionStr; AH->archiveRemoteVersion = AH->public.remoteVersionStr;
...@@ -150,11 +151,8 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ...@@ -150,11 +151,8 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
do do
{ {
#define PARAMS_ARRAY_SIZE 7 #define PARAMS_ARRAY_SIZE 7
const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
if (!keywords || !values)
die_horribly(AH, modulename, "out of memory\n");
keywords[0] = "host"; keywords[0] = "host";
values[0] = PQhost(AH->connection); values[0] = PQhost(AH->connection);
...@@ -257,11 +255,8 @@ ConnectDatabase(Archive *AHX, ...@@ -257,11 +255,8 @@ ConnectDatabase(Archive *AHX,
do do
{ {
#define PARAMS_ARRAY_SIZE 7 #define PARAMS_ARRAY_SIZE 7
const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
if (!keywords || !values)
die_horribly(AH, modulename, "out of memory\n");
keywords[0] = "host"; keywords[0] = "host";
values[0] = pghost; values[0] = pghost;
...@@ -397,10 +392,8 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen) ...@@ -397,10 +392,8 @@ ExecuteSqlCommandBuf(ArchiveHandle *AH, const char *buf, size_t bufLen)
ExecuteSqlCommand(AH, buf, "could not execute query"); ExecuteSqlCommand(AH, buf, "could not execute query");
else else
{ {
char *str = (char *) malloc(bufLen + 1); char *str = (char *) pg_malloc(bufLen + 1);
if (!str)
die_horribly(AH, modulename, "out of memory\n");
memcpy(str, buf, bufLen); memcpy(str, buf, bufLen);
str[bufLen] = '\0'; str[bufLen] = '\0';
ExecuteSqlCommand(AH, str, "could not execute query"); ExecuteSqlCommand(AH, str, "could not execute query");
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
*/ */
#include "compress_io.h" #include "compress_io.h"
#include "common.h"
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
...@@ -125,9 +126,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) ...@@ -125,9 +126,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
AH->DeClonePtr = NULL; AH->DeClonePtr = NULL;
/* Set up our private context */ /* Set up our private context */
ctx = (lclContext *) calloc(1, sizeof(lclContext)); ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
if (ctx == NULL)
die_horribly(AH, modulename, "out of memory\n");
AH->formatData = (void *) ctx; AH->formatData = (void *) ctx;
ctx->dataFH = NULL; ctx->dataFH = NULL;
...@@ -135,9 +134,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) ...@@ -135,9 +134,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
/* Initialize LO buffering */ /* Initialize LO buffering */
AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf_size = LOBBUFSIZE;
AH->lo_buf = (void *) malloc(LOBBUFSIZE); AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
if (AH->lo_buf == NULL)
die_horribly(AH, modulename, "out of memory\n");
/* /*
* Now open the TOC file * Now open the TOC file
...@@ -196,16 +193,14 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) ...@@ -196,16 +193,14 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
lclTocEntry *tctx; lclTocEntry *tctx;
char fn[MAXPGPATH]; char fn[MAXPGPATH];
tctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); tctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
if (!tctx)
die_horribly(AH, modulename, "out of memory\n");
if (te->dataDumper) if (te->dataDumper)
{ {
snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId); snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId);
tctx->filename = strdup(fn); tctx->filename = pg_strdup(fn);
} }
else if (strcmp(te->desc, "BLOBS") == 0) else if (strcmp(te->desc, "BLOBS") == 0)
tctx->filename = strdup("blobs.toc"); tctx->filename = pg_strdup("blobs.toc");
else else
tctx->filename = NULL; tctx->filename = NULL;
...@@ -247,9 +242,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te) ...@@ -247,9 +242,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
if (tctx == NULL) if (tctx == NULL)
{ {
tctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); tctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
if (!tctx)
die_horribly(AH, modulename, "out of memory\n");
te->formatData = (void *) tctx; te->formatData = (void *) tctx;
} }
...@@ -355,9 +348,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt) ...@@ -355,9 +348,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename, RestoreOptions *ropt)
die_horribly(AH, modulename, "could not open input file \"%s\": %s\n", die_horribly(AH, modulename, "could not open input file \"%s\": %s\n",
filename, strerror(errno)); filename, strerror(errno));
buf = malloc(ZLIB_OUT_SIZE); buf = pg_malloc(ZLIB_OUT_SIZE);
if (buf == NULL)
die_horribly(NULL, modulename, "out of memory\n");
buflen = ZLIB_OUT_SIZE; buflen = ZLIB_OUT_SIZE;
while ((cnt = cfread(buf, buflen, cfp))) while ((cnt = cfread(buf, buflen, cfp)))
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
*/ */
#include "pg_backup_archiver.h" #include "pg_backup_archiver.h"
#include "common.h"
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te); static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
static void _StartData(ArchiveHandle *AH, TocEntry *te); static void _StartData(ArchiveHandle *AH, TocEntry *te);
...@@ -103,15 +104,13 @@ InitArchiveFmt_Files(ArchiveHandle *AH) ...@@ -103,15 +104,13 @@ InitArchiveFmt_Files(ArchiveHandle *AH)
/* /*
* Set up some special context used in compressing data. * Set up some special context used in compressing data.
*/ */
ctx = (lclContext *) calloc(1, sizeof(lclContext)); ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
AH->formatData = (void *) ctx; AH->formatData = (void *) ctx;
ctx->filePos = 0; ctx->filePos = 0;
/* Initialize LO buffering */ /* Initialize LO buffering */
AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf_size = LOBBUFSIZE;
AH->lo_buf = (void *) malloc(LOBBUFSIZE); AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
if (AH->lo_buf == NULL)
die_horribly(AH, modulename, "out of memory\n");
/* /*
* Now open the TOC file * Now open the TOC file
...@@ -183,7 +182,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) ...@@ -183,7 +182,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
lclTocEntry *ctx; lclTocEntry *ctx;
char fn[K_STD_BUF_SIZE]; char fn[K_STD_BUF_SIZE];
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
if (te->dataDumper) if (te->dataDumper)
{ {
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
...@@ -194,7 +193,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) ...@@ -194,7 +193,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
#else #else
sprintf(fn, "%d.dat", te->dumpId); sprintf(fn, "%d.dat", te->dumpId);
#endif #endif
ctx->filename = strdup(fn); ctx->filename = pg_strdup(fn);
} }
else else
{ {
...@@ -222,7 +221,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te) ...@@ -222,7 +221,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
if (ctx == NULL) if (ctx == NULL)
{ {
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
te->formatData = (void *) ctx; te->formatData = (void *) ctx;
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include "pg_backup_archiver.h" #include "pg_backup_archiver.h"
#include "common.h"
#include "dumputils.h" #include "dumputils.h"
#include <unistd.h> /* for dup */ #include <unistd.h> /* for dup */
...@@ -67,9 +68,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH) ...@@ -67,9 +68,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH)
/* Initialize LO buffering */ /* Initialize LO buffering */
AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf_size = LOBBUFSIZE;
AH->lo_buf = (void *) malloc(LOBBUFSIZE); AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
if (AH->lo_buf == NULL)
die_horribly(AH, NULL, "out of memory\n");
/* /*
* Now prevent reading... * Now prevent reading...
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "pg_backup.h" #include "pg_backup.h"
#include "pg_backup_archiver.h" #include "pg_backup_archiver.h"
#include "pg_backup_tar.h" #include "pg_backup_tar.h"
#include "common.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
...@@ -159,16 +160,14 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) ...@@ -159,16 +160,14 @@ InitArchiveFmt_Tar(ArchiveHandle *AH)
/* /*
* Set up some special context used in compressing data. * Set up some special context used in compressing data.
*/ */
ctx = (lclContext *) calloc(1, sizeof(lclContext)); ctx = (lclContext *) pg_calloc(1, sizeof(lclContext));
AH->formatData = (void *) ctx; AH->formatData = (void *) ctx;
ctx->filePos = 0; ctx->filePos = 0;
ctx->isSpecialScript = 0; ctx->isSpecialScript = 0;
/* Initialize LO buffering */ /* Initialize LO buffering */
AH->lo_buf_size = LOBBUFSIZE; AH->lo_buf_size = LOBBUFSIZE;
AH->lo_buf = (void *) malloc(LOBBUFSIZE); AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);
if (AH->lo_buf == NULL)
die_horribly(AH, modulename, "out of memory\n");
/* /*
* Now open the tar file, and load the TOC if we're in read mode. * Now open the tar file, and load the TOC if we're in read mode.
...@@ -267,7 +266,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) ...@@ -267,7 +266,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
lclTocEntry *ctx; lclTocEntry *ctx;
char fn[K_STD_BUF_SIZE]; char fn[K_STD_BUF_SIZE];
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
if (te->dataDumper != NULL) if (te->dataDumper != NULL)
{ {
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
...@@ -278,7 +277,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) ...@@ -278,7 +277,7 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
#else #else
sprintf(fn, "%d.dat", te->dumpId); sprintf(fn, "%d.dat", te->dumpId);
#endif #endif
ctx->filename = strdup(fn); ctx->filename = pg_strdup(fn);
} }
else else
{ {
...@@ -306,7 +305,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te) ...@@ -306,7 +305,7 @@ _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
if (ctx == NULL) if (ctx == NULL)
{ {
ctx = (lclTocEntry *) calloc(1, sizeof(lclTocEntry)); ctx = (lclTocEntry *) pg_calloc(1, sizeof(lclTocEntry));
te->formatData = (void *) ctx; te->formatData = (void *) ctx;
} }
...@@ -379,7 +378,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) ...@@ -379,7 +378,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
} }
else else
{ {
tm = calloc(1, sizeof(TAR_MEMBER)); tm = pg_calloc(1, sizeof(TAR_MEMBER));
#ifndef WIN32 #ifndef WIN32
tm->tmpFH = tmpfile(); tm->tmpFH = tmpfile();
...@@ -432,7 +431,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) ...@@ -432,7 +431,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode)
#endif #endif
tm->AH = AH; tm->AH = AH;
tm->targetFile = strdup(filename); tm->targetFile = pg_strdup(filename);
} }
tm->mode = mode; tm->mode = mode;
...@@ -665,7 +664,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt) ...@@ -665,7 +664,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
ahprintf(AH, "\\.\n"); ahprintf(AH, "\\.\n");
/* Get a copy of the COPY statement and clean it up */ /* Get a copy of the COPY statement and clean it up */
tmpCopy = strdup(te->copyStmt); tmpCopy = pg_strdup(te->copyStmt);
for (i = 0; i < strlen(tmpCopy); i++) for (i = 0; i < strlen(tmpCopy); i++)
tmpCopy[i] = pg_tolower((unsigned char) tmpCopy[i]); tmpCopy[i] = pg_tolower((unsigned char) tmpCopy[i]);
...@@ -1010,9 +1009,7 @@ tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) ...@@ -1010,9 +1009,7 @@ tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...)
if (p != NULL) if (p != NULL)
free(p); free(p);
bSize *= 2; bSize *= 2;
p = (char *) malloc(bSize); p = (char *) pg_malloc(bSize);
if (p == NULL)
die_horribly(AH, modulename, "out of memory\n");
va_start(ap, fmt); va_start(ap, fmt);
cnt = vsnprintf(p, bSize, fmt, ap); cnt = vsnprintf(p, bSize, fmt, ap);
va_end(ap); va_end(ap);
...@@ -1125,7 +1122,7 @@ static TAR_MEMBER * ...@@ -1125,7 +1122,7 @@ static TAR_MEMBER *
_tarPositionTo(ArchiveHandle *AH, const char *filename) _tarPositionTo(ArchiveHandle *AH, const char *filename)
{ {
lclContext *ctx = (lclContext *) AH->formatData; lclContext *ctx = (lclContext *) AH->formatData;
TAR_MEMBER *th = calloc(1, sizeof(TAR_MEMBER)); TAR_MEMBER *th = pg_calloc(1, sizeof(TAR_MEMBER));
char c; char c;
char header[512]; char header[512];
size_t i, size_t i,
...@@ -1295,7 +1292,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) ...@@ -1295,7 +1292,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
tag, sum, chk, buf); tag, sum, chk, buf);
} }
th->targetFile = strdup(tag); th->targetFile = pg_strdup(tag);
th->fileLen = len; th->fileLen = len;
return 1; return 1;
......
This diff is collapsed.
...@@ -521,11 +521,6 @@ extern void simple_string_list_append(SimpleStringList *list, const char *val); ...@@ -521,11 +521,6 @@ extern void simple_string_list_append(SimpleStringList *list, const char *val);
extern bool simple_oid_list_member(SimpleOidList *list, Oid val); extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
extern bool simple_string_list_member(SimpleStringList *list, const char *val); extern bool simple_string_list_member(SimpleStringList *list, const char *val);
extern char *pg_strdup(const char *string);
extern void *pg_malloc(size_t size);
extern void *pg_calloc(size_t nmemb, size_t size);
extern void *pg_realloc(void *ptr, size_t size);
extern void check_conn_and_db(void); extern void check_conn_and_db(void);
extern void exit_nicely(void); extern void exit_nicely(void);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "pg_backup_archiver.h" #include "pg_backup_archiver.h"
#include "common.h"
static const char *modulename = gettext_noop("sorter"); static const char *modulename = gettext_noop("sorter");
...@@ -227,10 +227,7 @@ sortDumpableObjects(DumpableObject **objs, int numObjs) ...@@ -227,10 +227,7 @@ sortDumpableObjects(DumpableObject **objs, int numObjs)
if (numObjs <= 0) if (numObjs <= 0)
return; return;
ordering = (DumpableObject **) malloc(numObjs * sizeof(DumpableObject *)); ordering = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *));
if (ordering == NULL)
exit_horribly(NULL, modulename, "out of memory\n");
while (!TopoSort(objs, numObjs, ordering, &nOrdering)) while (!TopoSort(objs, numObjs, ordering, &nOrdering))
findDependencyLoops(ordering, nOrdering, numObjs); findDependencyLoops(ordering, nOrdering, numObjs);
...@@ -301,9 +298,7 @@ TopoSort(DumpableObject **objs, ...@@ -301,9 +298,7 @@ TopoSort(DumpableObject **objs,
return true; return true;
/* Create workspace for the above-described heap */ /* Create workspace for the above-described heap */
pendingHeap = (int *) malloc(numObjs * sizeof(int)); pendingHeap = (int *) pg_malloc(numObjs * sizeof(int));
if (pendingHeap == NULL)
exit_horribly(NULL, modulename, "out of memory\n");
/* /*
* Scan the constraints, and for each item in the input, generate a count * Scan the constraints, and for each item in the input, generate a count
...@@ -312,13 +307,9 @@ TopoSort(DumpableObject **objs, ...@@ -312,13 +307,9 @@ TopoSort(DumpableObject **objs,
* We also make a map showing the input-order index of the item with * We also make a map showing the input-order index of the item with
* dumpId j. * dumpId j.
*/ */
beforeConstraints = (int *) malloc((maxDumpId + 1) * sizeof(int)); beforeConstraints = (int *) pg_malloc((maxDumpId + 1) * sizeof(int));
if (beforeConstraints == NULL)
exit_horribly(NULL, modulename, "out of memory\n");
memset(beforeConstraints, 0, (maxDumpId + 1) * sizeof(int)); memset(beforeConstraints, 0, (maxDumpId + 1) * sizeof(int));
idMap = (int *) malloc((maxDumpId + 1) * sizeof(int)); idMap = (int *) pg_malloc((maxDumpId + 1) * sizeof(int));
if (idMap == NULL)
exit_horribly(NULL, modulename, "out of memory\n");
for (i = 0; i < numObjs; i++) for (i = 0; i < numObjs; i++)
{ {
obj = objs[i]; obj = objs[i];
...@@ -516,9 +507,7 @@ findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs) ...@@ -516,9 +507,7 @@ findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs)
bool fixedloop; bool fixedloop;
int i; int i;
workspace = (DumpableObject **) malloc(totObjs * sizeof(DumpableObject *)); workspace = (DumpableObject **) pg_malloc(totObjs * sizeof(DumpableObject *));
if (workspace == NULL)
exit_horribly(NULL, modulename, "out of memory\n");
initiallen = 0; initiallen = 0;
fixedloop = false; fixedloop = false;
......
...@@ -60,6 +60,9 @@ static PGconn *connectDatabase(const char *dbname, const char *pghost, const cha ...@@ -60,6 +60,9 @@ static PGconn *connectDatabase(const char *dbname, const char *pghost, const cha
static PGresult *executeQuery(PGconn *conn, const char *query); static PGresult *executeQuery(PGconn *conn, const char *query);
static void executeCommand(PGconn *conn, const char *query); static void executeCommand(PGconn *conn, const char *query);
char *pg_strdup(const char *string);
void *pg_malloc(size_t size);
static char pg_dump_bin[MAXPGPATH]; static char pg_dump_bin[MAXPGPATH];
static PQExpBuffer pgdumpopts; static PQExpBuffer pgdumpopts;
static bool skip_acls = false; static bool skip_acls = false;
...@@ -916,7 +919,7 @@ dumpGroups(PGconn *conn) ...@@ -916,7 +919,7 @@ dumpGroups(PGconn *conn)
if (strlen(grolist) < 3) if (strlen(grolist) < 3)
continue; continue;
grolist = strdup(grolist); grolist = pg_strdup(grolist);
grolist[0] = '('; grolist[0] = '(';
grolist[strlen(grolist) - 1] = ')'; grolist[strlen(grolist) - 1] = ')';
printfPQExpBuffer(buf, printfPQExpBuffer(buf,
...@@ -1040,7 +1043,7 @@ dumpTablespaces(PGconn *conn) ...@@ -1040,7 +1043,7 @@ dumpTablespaces(PGconn *conn)
char *fspcname; char *fspcname;
/* needed for buildACLCommands() */ /* needed for buildACLCommands() */
fspcname = strdup(fmtId(spcname)); fspcname = pg_strdup(fmtId(spcname));
appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname); appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner)); appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
...@@ -1189,11 +1192,11 @@ dumpCreateDB(PGconn *conn) ...@@ -1189,11 +1192,11 @@ dumpCreateDB(PGconn *conn)
if (PQntuples(res) > 0) if (PQntuples(res) > 0)
{ {
if (!PQgetisnull(res, 0, 0)) if (!PQgetisnull(res, 0, 0))
default_encoding = strdup(PQgetvalue(res, 0, 0)); default_encoding = pg_strdup(PQgetvalue(res, 0, 0));
if (!PQgetisnull(res, 0, 1)) if (!PQgetisnull(res, 0, 1))
default_collate = strdup(PQgetvalue(res, 0, 1)); default_collate = pg_strdup(PQgetvalue(res, 0, 1));
if (!PQgetisnull(res, 0, 2)) if (!PQgetisnull(res, 0, 2))
default_ctype = strdup(PQgetvalue(res, 0, 2)); default_ctype = pg_strdup(PQgetvalue(res, 0, 2));
} }
PQclear(res); PQclear(res);
...@@ -1283,7 +1286,7 @@ dumpCreateDB(PGconn *conn) ...@@ -1283,7 +1286,7 @@ dumpCreateDB(PGconn *conn)
char *dbtablespace = PQgetvalue(res, i, 9); char *dbtablespace = PQgetvalue(res, i, 9);
char *fdbname; char *fdbname;
fdbname = strdup(fmtId(dbname)); fdbname = pg_strdup(fmtId(dbname));
resetPQExpBuffer(buf); resetPQExpBuffer(buf);
...@@ -1519,7 +1522,7 @@ makeAlterConfigCommand(PGconn *conn, const char *arrayitem, ...@@ -1519,7 +1522,7 @@ makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
char *mine; char *mine;
PQExpBuffer buf = createPQExpBuffer(); PQExpBuffer buf = createPQExpBuffer();
mine = strdup(arrayitem); mine = pg_strdup(arrayitem);
pos = strchr(mine, '='); pos = strchr(mine, '=');
if (pos == NULL) if (pos == NULL)
return; return;
...@@ -1688,14 +1691,8 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, ...@@ -1688,14 +1691,8 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
do do
{ {
#define PARAMS_ARRAY_SIZE 7 #define PARAMS_ARRAY_SIZE 7
const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
if (!keywords || !values)
{
fprintf(stderr, _("%s: out of memory\n"), progname);
exit(1);
}
keywords[0] = "host"; keywords[0] = "host";
values[0] = pghost; values[0] = pghost;
...@@ -1911,3 +1908,41 @@ doShellQuoting(PQExpBuffer buf, const char *str) ...@@ -1911,3 +1908,41 @@ doShellQuoting(PQExpBuffer buf, const char *str)
appendPQExpBufferChar(buf, '"'); appendPQExpBufferChar(buf, '"');
#endif /* WIN32 */ #endif /* WIN32 */
} }
/*
* Simpler versions of common.c functions.
*/
char *
pg_strdup(const char *string)
{
char *tmp;
if (!string)
{
fprintf(stderr, "cannot duplicate null pointer\n");
exit(1);
}
tmp = strdup(string);
if (!tmp)
{
fprintf(stderr, _("%s: out of memory\n"), progname);
exit(1);
}
return tmp;
}
void *
pg_malloc(size_t size)
{
void *tmp;
tmp = malloc(size);
if (!tmp)
{
fprintf(stderr, _("%s: out of memory\n"), progname);
exit(1);
}
return tmp;
}
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "common.h"
#include "pg_backup_archiver.h" #include "pg_backup_archiver.h"
#include "dumputils.h" #include "dumputils.h"
...@@ -159,21 +160,21 @@ main(int argc, char **argv) ...@@ -159,21 +160,21 @@ main(int argc, char **argv)
opts->createDB = 1; opts->createDB = 1;
break; break;
case 'd': case 'd':
opts->dbname = strdup(optarg); opts->dbname = pg_strdup(optarg);
break; break;
case 'e': case 'e':
opts->exit_on_error = true; opts->exit_on_error = true;
break; break;
case 'f': /* output file name */ case 'f': /* output file name */
opts->filename = strdup(optarg); opts->filename = pg_strdup(optarg);
break; break;
case 'F': case 'F':
if (strlen(optarg) != 0) if (strlen(optarg) != 0)
opts->formatName = strdup(optarg); opts->formatName = pg_strdup(optarg);
break; break;
case 'h': case 'h':
if (strlen(optarg) != 0) if (strlen(optarg) != 0)
opts->pghost = strdup(optarg); opts->pghost = pg_strdup(optarg);
break; break;
case 'i': case 'i':
/* ignored, deprecated option */ /* ignored, deprecated option */
...@@ -188,11 +189,11 @@ main(int argc, char **argv) ...@@ -188,11 +189,11 @@ main(int argc, char **argv)
break; break;
case 'L': /* input TOC summary file name */ case 'L': /* input TOC summary file name */
opts->tocFile = strdup(optarg); opts->tocFile = pg_strdup(optarg);
break; break;
case 'n': /* Dump data for this schema only */ case 'n': /* Dump data for this schema only */
opts->schemaNames = strdup(optarg); opts->schemaNames = pg_strdup(optarg);
break; break;
case 'O': case 'O':
...@@ -201,7 +202,7 @@ main(int argc, char **argv) ...@@ -201,7 +202,7 @@ main(int argc, char **argv)
case 'p': case 'p':
if (strlen(optarg) != 0) if (strlen(optarg) != 0)
opts->pgport = strdup(optarg); opts->pgport = pg_strdup(optarg);
break; break;
case 'R': case 'R':
/* no-op, still accepted for backwards compatibility */ /* no-op, still accepted for backwards compatibility */
...@@ -209,29 +210,29 @@ main(int argc, char **argv) ...@@ -209,29 +210,29 @@ main(int argc, char **argv)
case 'P': /* Function */ case 'P': /* Function */
opts->selTypes = 1; opts->selTypes = 1;
opts->selFunction = 1; opts->selFunction = 1;
opts->functionNames = strdup(optarg); opts->functionNames = pg_strdup(optarg);
break; break;
case 'I': /* Index */ case 'I': /* Index */
opts->selTypes = 1; opts->selTypes = 1;
opts->selIndex = 1; opts->selIndex = 1;
opts->indexNames = strdup(optarg); opts->indexNames = pg_strdup(optarg);
break; break;
case 'T': /* Trigger */ case 'T': /* Trigger */
opts->selTypes = 1; opts->selTypes = 1;
opts->selTrigger = 1; opts->selTrigger = 1;
opts->triggerNames = strdup(optarg); opts->triggerNames = pg_strdup(optarg);
break; break;
case 's': /* dump schema only */ case 's': /* dump schema only */
opts->schemaOnly = 1; opts->schemaOnly = 1;
break; break;
case 'S': /* Superuser username */ case 'S': /* Superuser username */
if (strlen(optarg) != 0) if (strlen(optarg) != 0)
opts->superuser = strdup(optarg); opts->superuser = pg_strdup(optarg);
break; break;
case 't': /* Dump data for this table only */ case 't': /* Dump data for this table only */
opts->selTypes = 1; opts->selTypes = 1;
opts->selTable = 1; opts->selTable = 1;
opts->tableNames = strdup(optarg); opts->tableNames = pg_strdup(optarg);
break; break;
case 'U': case 'U':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment