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

📄 pg_backup_archiver.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 4 页
字号:
	va_start(ap, fmt);	_die_horribly(AH, modulename, fmt, 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;	te->_moved = 1;}static 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;	te->_moved = 1;}static TocEntry *_getTocEntry(ArchiveHandle *AH, int id){	TocEntry   *te;	te = AH->toc->next;	while (te != AH->toc)	{		if (te->id == id)			return te;		te = te->next;	}	return NULL;}intTocIDRequired(ArchiveHandle *AH, int id, RestoreOptions *ropt){	TocEntry   *te = _getTocEntry(AH, id);	if (!te)		return 0;	return _tocEntryRequired(te, ropt);}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);	AH->lastID = 0;	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->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;#if 0	write_msg(modulename, "archive format is %d\n", fmt);#endif	if (fmt == archUnknown)		AH->format = _discoverArchiveFormat(AH);	else		AH->format = fmt;	switch (AH->format)	{		case archCustom:			InitArchiveFmt_Custom(AH);			break;		case archFiles:			InitArchiveFmt_Files(AH);			break;		case archNull:			InitArchiveFmt_Null(AH);			break;		case archTar:			InitArchiveFmt_Tar(AH);			break;		default:			die_horribly(AH, modulename, "unrecognized file format \"%d\"\n", fmt);	}	return AH;}voidWriteDataChunks(ArchiveHandle *AH){	TocEntry   *te = AH->toc->next;	StartDataPtr startPtr;	EndDataPtr	endPtr;	while (te != AH->toc)	{		if (te->dataDumper != NULL)		{			AH->currToc = te;			/* printf("Writing data for %d (%x)\n", te->id, te); */			if (strcmp(te->desc, "BLOBS") == 0)			{				startPtr = AH->StartBlobsPtr;				endPtr = AH->EndBlobsPtr;			}			else			{				startPtr = AH->StartDataPtr;				endPtr = AH->EndDataPtr;			}			if (startPtr != NULL)				(*startPtr) (AH, te);			/*			 * printf("Dumper arg for %d is %x\n", te->id,			 * te->dataDumperArg);			 */			/*			 * The user-provided DataDumper routine needs to call			 * AH->WriteData			 */			(*te->dataDumper) ((Archive *) AH, te->oid, te->dataDumperArg);			if (endPtr != NULL)				(*endPtr) (AH, te);			AH->currToc = NULL;		}		te = te->next;	}}voidWriteToc(ArchiveHandle *AH){	TocEntry   *te = AH->toc->next;	const char *dep;	int			i;	/* printf("%d TOC Entries to save\n", AH->tocCount); */	WriteInt(AH, AH->tocCount);	while (te != AH->toc)	{		WriteInt(AH, te->id);		WriteInt(AH, te->dataDumper ? 1 : 0);		WriteStr(AH, te->oid);		WriteStr(AH, te->tag);		WriteStr(AH, te->desc);		WriteStr(AH, te->defn);		WriteStr(AH, te->dropStmt);		WriteStr(AH, te->copyStmt);		WriteStr(AH, te->namespace);		WriteStr(AH, te->owner);		/* Dump list of dependencies */		if (te->depOid != NULL)		{			i = 0;			while ((dep = (*te->depOid)[i++]) != NULL)				WriteStr(AH, dep);		}		WriteStr(AH, NULL);		/* Terminate List */		if (AH->WriteExtraTocPtr)			(*AH->WriteExtraTocPtr) (AH, te);		te = te->next;	}}voidReadToc(ArchiveHandle *AH){	int			i;	char	   *((*deps)[]);	int			depIdx;	int			depSize;	TocEntry   *te = AH->toc->next;	AH->tocCount = ReadInt(AH);	for (i = 0; i < AH->tocCount; i++)	{		te = (TocEntry *) calloc(1, sizeof(TocEntry));		te->id = ReadInt(AH);		/* Sanity check */		if (te->id <= 0 || te->id > AH->tocCount)			die_horribly(AH, modulename, "entry ID %d out of range -- perhaps a corrupt TOC\n", te->id);		te->hadDumper = ReadInt(AH);		te->oid = ReadStr(AH);		te->oidVal = atooid(te->oid);		te->tag = ReadStr(AH);		te->desc = ReadStr(AH);		te->defn = ReadStr(AH);		te->dropStmt = ReadStr(AH);		if (AH->version >= K_VERS_1_3)			te->copyStmt = ReadStr(AH);		if (AH->version >= K_VERS_1_6)			te->namespace = ReadStr(AH);		te->owner = ReadStr(AH);		/* Read TOC entry dependencies */		if (AH->version >= K_VERS_1_5)		{			depSize = 100;			deps = malloc(sizeof(char *) * depSize);			depIdx = 0;			do			{				if (depIdx >= depSize)				{					depSize *= 2;					deps = realloc(deps, sizeof(char *) * depSize);				}				(*deps)[depIdx] = ReadStr(AH);#if 0				if ((*deps)[depIdx])					write_msg(modulename, "read dependency for %s -> %s\n",							  te->tag, (*deps)[depIdx]);#endif			} while ((*deps)[depIdx++] != NULL);			if (depIdx > 1)		/* We have a non-null entry */				te->depOid = realloc(deps, sizeof(char *) * depIdx);	/* trim it */			else			{				free(deps);				te->depOid = NULL;		/* no deps */			}		}		else			te->depOid = NULL;		/* Set maxOidVal etc for use in sorting */		_fixupOidInfo(te);		if (AH->ReadExtraTocPtr)			(*AH->ReadExtraTocPtr) (AH, te);		ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n", i, te->id, te->desc, te->tag);		te->prev = AH->toc->prev;		AH->toc->prev->next = te;		AH->toc->prev = te;		te->next = AH->toc;	}}static teReqs_tocEntryRequired(TocEntry *te, RestoreOptions *ropt){	teReqs		res = 3;		/* Schema = 1, Data = 2, Both = 3 */	/* ENCODING objects are dumped specially, so always reject here */	if (strcmp(te->desc, "ENCODING") == 0)		return 0;	/* If it's an ACL, maybe ignore it */	if (ropt->aclsSkip && strcmp(te->desc, "ACL") == 0)		return 0;	if (!ropt->create && strcmp(te->desc, "DATABASE") == 0)		return 0;

⌨️ 快捷键说明

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