⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pg_backup_archiver.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
			return res;		}	}}/* Common exit code */static void_write_msg(const char *modulename, const char *fmt, va_list ap){	if (modulename)		fprintf(stderr, "%s: [%s] ", progname, _(modulename));	else		fprintf(stderr, "%s: ", progname);	vfprintf(stderr, _(fmt), ap);}voidwrite_msg(const char *modulename, const char *fmt,...){	va_list		ap;	va_start(ap, fmt);	_write_msg(modulename, fmt, ap);	va_end(ap);}static void_die_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt, va_list ap){	_write_msg(modulename, fmt, ap);	if (AH)	{		if (AH->public.verbose)			write_msg(NULL, "*** aborted because of error\n");		if (AH->connection)			PQfinish(AH->connection);	}	exit(1);}/* External use */voidexit_horribly(Archive *AH, const char *modulename, const char *fmt,...){	va_list		ap;	va_start(ap, fmt);	_die_horribly((ArchiveHandle *) AH, modulename, fmt, ap);	va_end(ap);}/* Archiver use (just different arg declaration) */voiddie_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...){	va_list		ap;	va_start(ap, fmt);	_die_horribly(AH, modulename, fmt, ap);	va_end(ap);}/* on some error, we may decide to go on... */voidwarn_or_die_horribly(ArchiveHandle *AH,					 const char *modulename, const char *fmt,...){	va_list		ap;	switch (AH->stage)	{		case STAGE_NONE:			/* Do nothing special */			break;		case STAGE_INITIALIZING:			if (AH->stage != AH->lastErrorStage)				write_msg(modulename, "Error while INITIALIZING:\n");			break;		case STAGE_PROCESSING:			if (AH->stage != AH->lastErrorStage)				write_msg(modulename, "Error while PROCESSING TOC:\n");			break;		case STAGE_FINALIZING:			if (AH->stage != AH->lastErrorStage)				write_msg(modulename, "Error while FINALIZING:\n");			break;	}	if (AH->currentTE != NULL && AH->currentTE != AH->lastErrorTE)	{		write_msg(modulename, "Error from TOC entry %d; %u %u %s %s %s\n",				  AH->currentTE->dumpId,			 AH->currentTE->catalogId.tableoid, AH->currentTE->catalogId.oid,			  AH->currentTE->desc, AH->currentTE->tag, AH->currentTE->owner);	}	AH->lastErrorStage = AH->stage;	AH->lastErrorTE = AH->currentTE;	va_start(ap, fmt);	if (AH->public.exit_on_error)		_die_horribly(AH, modulename, fmt, ap);	else	{		_write_msg(modulename, fmt, ap);		AH->public.n_errors++;	}	va_end(ap);}static void_moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te){	te->prev->next = te->next;	te->next->prev = te->prev;	te->prev = pos;	te->next = pos->next;	pos->next->prev = te;	pos->next = te;}#ifdef NOT_USEDstatic void_moveBefore(ArchiveHandle *AH, TocEntry *pos, TocEntry *te){	te->prev->next = te->next;	te->next->prev = te->prev;	te->prev = pos->prev;	te->next = pos;	pos->prev->next = te;	pos->prev = te;}#endifstatic TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id){	TocEntry   *te;	te = AH->toc->next;	while (te != AH->toc)	{		if (te->dumpId == id)			return te;		te = te->next;	}	return NULL;}teReqsTocIDRequired(ArchiveHandle *AH, DumpId id, RestoreOptions *ropt){	TocEntry   *te = getTocEntryByDumpId(AH, id);	if (!te)		return 0;	return _tocEntryRequired(te, ropt, true);}size_tWriteOffset(ArchiveHandle *AH, off_t o, int wasSet){	int			off;	/* Save the flag */	(*AH->WriteBytePtr) (AH, wasSet);	/* Write out off_t smallest byte first, prevents endian mismatch */	for (off = 0; off < sizeof(off_t); off++)	{		(*AH->WriteBytePtr) (AH, o & 0xFF);		o >>= 8;	}	return sizeof(off_t) + 1;}intReadOffset(ArchiveHandle *AH, off_t *o){	int			i;	int			off;	int			offsetFlg;	/* Initialize to zero */	*o = 0;	/* Check for old version */	if (AH->version < K_VERS_1_7)	{		/* Prior versions wrote offsets using WriteInt */		i = ReadInt(AH);		/* -1 means not set */		if (i < 0)			return K_OFFSET_POS_NOT_SET;		else if (i == 0)			return K_OFFSET_NO_DATA;		/* Cast to off_t because it was written as an int. */		*o = (off_t) i;		return K_OFFSET_POS_SET;	}	/*	 * Read the flag indicating the state of the data pointer. Check if valid	 * and die if not.	 *	 * This used to be handled by a negative or zero pointer, now we use an	 * extra byte specifically for the state.	 */	offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF;	switch (offsetFlg)	{		case K_OFFSET_POS_NOT_SET:		case K_OFFSET_NO_DATA:		case K_OFFSET_POS_SET:			break;		default:			die_horribly(AH, modulename, "Unexpected data offset flag %d\n", offsetFlg);	}	/*	 * Read the bytes	 */	for (off = 0; off < AH->offSize; off++)	{		if (off < sizeof(off_t))			*o |= ((off_t) ((*AH->ReadBytePtr) (AH))) << (off * 8);		else		{			if ((*AH->ReadBytePtr) (AH) != 0)				die_horribly(AH, modulename, "file offset in dump file is too large\n");		}	}	return offsetFlg;}size_tWriteInt(ArchiveHandle *AH, int i){	int			b;	/*	 * This is a bit yucky, but I don't want to make the binary format very	 * dependent on representation, and not knowing much about it, I write out	 * a sign byte. If you change this, don't forget to change the file	 * version #, and modify readInt to read the new format AS WELL AS the old	 * formats.	 */	/* SIGN byte */	if (i < 0)	{		(*AH->WriteBytePtr) (AH, 1);		i = -i;	}	else		(*AH->WriteBytePtr) (AH, 0);	for (b = 0; b < AH->intSize; b++)	{		(*AH->WriteBytePtr) (AH, i & 0xFF);		i >>= 8;	}	return AH->intSize + 1;}intReadInt(ArchiveHandle *AH){	int			res = 0;	int			bv,				b;	int			sign = 0;		/* Default positive */	int			bitShift = 0;	if (AH->version > K_VERS_1_0)		/* Read a sign byte */		sign = (*AH->ReadBytePtr) (AH);	for (b = 0; b < AH->intSize; b++)	{		bv = (*AH->ReadBytePtr) (AH) & 0xFF;		if (bv != 0)			res = res + (bv << bitShift);		bitShift += 8;	}	if (sign)		res = -res;	return res;}size_tWriteStr(ArchiveHandle *AH, const char *c){	size_t		res;	if (c)	{		res = WriteInt(AH, strlen(c));		res += (*AH->WriteBufPtr) (AH, c, strlen(c));	}	else		res = WriteInt(AH, -1);	return res;}char *ReadStr(ArchiveHandle *AH){	char	   *buf;	int			l;	l = ReadInt(AH);	if (l == -1)		buf = NULL;	else	{		buf = (char *) malloc(l + 1);		if (!buf)			die_horribly(AH, modulename, "out of memory\n");		(*AH->ReadBufPtr) (AH, (void *) buf, l);		buf[l] = '\0';	}	return buf;}static int_discoverArchiveFormat(ArchiveHandle *AH){	FILE	   *fh;	char		sig[6];			/* More than enough */	size_t		cnt;	int			wantClose = 0;#if 0	write_msg(modulename, "attempting to ascertain archive format\n");#endif	if (AH->lookahead)		free(AH->lookahead);	AH->lookaheadSize = 512;	AH->lookahead = calloc(1, 512);	AH->lookaheadLen = 0;	AH->lookaheadPos = 0;	if (AH->fSpec)	{		wantClose = 1;		fh = fopen(AH->fSpec, PG_BINARY_R);	}	else		fh = stdin;	if (!fh)		die_horribly(AH, modulename, "could not open input file: %s\n", strerror(errno));	cnt = fread(sig, 1, 5, fh);	if (cnt != 5)	{		if (ferror(fh))			die_horribly(AH, modulename, "could not read input file: %s\n", strerror(errno));		else			die_horribly(AH, modulename, "input file is too short (read %lu, expected 5)\n",						 (unsigned long) cnt);	}	/* Save it, just in case we need it later */	strncpy(&AH->lookahead[0], sig, 5);	AH->lookaheadLen = 5;	if (strncmp(sig, "PGDMP", 5) == 0)	{		AH->vmaj = fgetc(fh);		AH->vmin = fgetc(fh);		/* Save these too... */		AH->lookahead[AH->lookaheadLen++] = AH->vmaj;		AH->lookahead[AH->lookaheadLen++] = AH->vmin;		/* Check header version; varies from V1.0 */		if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0)))		/* Version > 1.0 */		{			AH->vrev = fgetc(fh);			AH->lookahead[AH->lookaheadLen++] = AH->vrev;		}		else			AH->vrev = 0;		/* Make a convenient integer <maj><min><rev>00 */		AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;		AH->intSize = fgetc(fh);		AH->lookahead[AH->lookaheadLen++] = AH->intSize;		if (AH->version >= K_VERS_1_7)		{			AH->offSize = fgetc(fh);			AH->lookahead[AH->lookaheadLen++] = AH->offSize;		}		else			AH->offSize = AH->intSize;		AH->format = fgetc(fh);		AH->lookahead[AH->lookaheadLen++] = AH->format;	}	else	{		/*		 * *Maybe* we have a tar archive format file... So, read first 512		 * byte header...		 */		cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);		AH->lookaheadLen += cnt;		if (AH->lookaheadLen != 512)			die_horribly(AH, modulename, "input file does not appear to be a valid archive (too short?)\n");		if (!isValidTarHeader(AH->lookahead))			die_horribly(AH, modulename, "input file does not appear to be a valid archive\n");		AH->format = archTar;	}	/* If we can't seek, then mark the header as read */	if (fseeko(fh, 0, SEEK_SET) != 0)	{		/*		 * NOTE: Formats that use the lookahead buffer can unset this in their		 * Init routine.		 */		AH->readHeader = 1;	}	else		AH->lookaheadLen = 0;	/* Don't bother since we've reset the file */#if 0	write_msg(modulename, "read %lu bytes into lookahead buffer\n",			  (unsigned long) AH->lookaheadLen);#endif	/* Close the file */	if (wantClose)		if (fclose(fh) != 0)			die_horribly(AH, modulename, "could not close the input file after reading header: %s\n",						 strerror(errno));	return AH->format;}/* * Allocate an archive handle */static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,		 const int compression, ArchiveMode mode){	ArchiveHandle *AH;#if 0	write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);#endif	AH = (ArchiveHandle *) calloc(1, sizeof(ArchiveHandle));	if (!AH)		die_horribly(AH, modulename, "out of memory\n");	/* AH->debugLevel = 100; */	AH->vmaj = K_VERS_MAJOR;	AH->vmin = K_VERS_MINOR;	AH->vrev = K_VERS_REV;	AH->createDate = time(NULL);	AH->intSize = sizeof(int);	AH->offSize = sizeof(off_t);	if (FileSpec)	{		AH->fSpec = strdup(FileSpec);		/*		 * Not used; maybe later....		 *		 * AH->workDir = strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;		 * i--) if (AH->workDir[i-1] == '/')		 */	}	else		AH->fSpec = NULL;	AH->currUser = strdup("");	/* So it's valid, but we can free() it later								 * if necessary */	AH->currSchema = strdup("");	/* ditto */	AH->currWithOids = -1;		/* force SET */	AH->toc = (TocEntry *) calloc(1, sizeof(TocEntry));	if (!AH->toc)		die_horribly(AH, modulename, "out of memory\n");	AH->toc->next = AH->toc;	AH->toc->prev = AH->toc;	AH->mode = mode;	AH->compression = compression;	AH->pgCopyBuf = createPQExpBuffer();	AH->sqlBuf = createPQExpBuffer();	/* Open stdout with no compression for AH output handle */	AH->gzOut = 0;	AH->OF = stdout;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -