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

📄 pgpsdacreate.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*__________________________________________________________________________
 Copyright (C) 2002 PGP Corporation
 All rights reserved.
 
 $Id: pgpSDACreate.c,v 1.32 2002/08/06 20:10:16 dallen Exp $
__________________________________________________________________________*/
#include "pgpSDACreate.h"
//#include "pgpSDA.h" included from SDA create... may be SEA see header
#ifdef WORDS_BIGENDIAN
#include "pgpEndianConversion.h"
#endif /* WORDS_BIGENDIAN */

// This is the structure that is passed into
// our getc_buffer and putc_buffer routines from
// LZSS. We need enough info here to read and write
// the cancel the file operations.
typedef struct
{
	FILE							*fin;
	FILE							*fout;
	SDAHEADER						*SDAHeader;
	PGPUInt32						blockindex;
	PGPUInt32						to_pointer;
	unsigned char					*outbuffer;
	unsigned char					*inbuffer;
	PGPSymmetricCipherContextRef	CASTContext;
	PGPError						err;
	FILELIST						*fl;
	PGPBoolean						bFeedFilename;
#ifdef E_BUSINESS_SERVER
	PGPBoolean						bPreserveDirectories;
#endif /* E_BUSINESS_SERVER */
	char							FileName[512];
	char 							*szOutputFileName;
#ifdef NO_64INT
	PGPUInt32						FileSize;
	PGPUInt32						FileIndex;
	PGPUInt32						FeedIndex;
#else /* !NO_64INT */
	PGPUInt64						FileSize;
	PGPUInt64						FileIndex;
	PGPUInt64						FeedIndex;
#endif /* NO_64INT */
	PGPUInt32						PathHead;
	PGPContextRef					context;
	SDACREATECALLBACK				UserProc;
	void							*pUserValue;
} GETPUTINFO;


#ifndef NO_64INT
#ifdef WORDS_BIGENDIAN
static
void
PGPUInt64ToLittleEndian(PGPUInt64 input, PGPByte *pOutput)
{
	PGPUInt32	second = (PGPUInt32)input;
	PGPUInt32	first = input >> 32;
	PGPUInt32	*pOut = (PGPUInt32 *)pOutput;

	PGPUInt32ToEndian(first, kPGPLittleEndian, (PGPByte *)&pOut[1]);
	PGPUInt32ToEndian(second, kPGPLittleEndian, (PGPByte *)&pOut[0]);
}
#endif /* WORDS_BIGENDIAN */
#endif /* NO_64INT */

#ifndef IS_SEA
	void 
CAST5encryptCFBdbl(
	PGPSymmetricCipherContextRef CASTContext,
	PGPUInt32			iv0, 
	PGPUInt32			iv1, 
	PGPUInt32			iv2, 
	PGPUInt32			iv3, 
	const PGPUInt32*	src, 
	PGPUInt32*			dest, 
	PGPUInt32			len)
{
	PGPError err;
	PGPUInt32 iv[4] = {iv0, iv1, iv2, iv3};
	while (len--) 
	{
		err=PGPSymmetricCipherEncrypt( CASTContext,
			(const PGPUInt8*) iv,
			(PGPUInt8*) iv);

//		We've replaced this restaurants original coffee with new
//		SDK coffee...

//		CAST5encrypt((const PGPUInt8*) iv, (PGPUInt8*) iv, xkey);
		*dest++	= iv[0]	^= *src++;
		*dest++	= iv[1]	^= *src++;

		err=PGPSymmetricCipherEncrypt( CASTContext,
			(const PGPUInt8*) (iv+2),
			(PGPUInt8*) (iv+2));

//		We've replaced this restaurants original coffee with new
//		SDK coffee...

//		CAST5encrypt((const PGPUInt8*) (iv+2), (PGPUInt8*) (iv+2), xkey);
		*dest++	= iv[2]	^= *src++;
		*dest++	= iv[3]	^= *src++;
	}
}

	void
EncryptBlock512(
	PGPSymmetricCipherContextRef CASTContext,
	SDAHEADER				*SDAHeader,
	PGPUInt32				blockNumber,
	const PGPUInt32 *		src,
	PGPUInt32 *				dest)
{
	int			i;
	PGPUInt32	sum0, sum1;
	PGPUInt32	iv0, iv1;

#ifdef WORDS_BIGENDIAN
	PGPUInt32	SUM0, SUM1;
	PGPUInt32	IV0, IV1;
	PGPUInt32	SRC;
	PGPUInt32	SRC0, SRC1;
	PGPUInt32	SALT0, SALT1;
	
	PGPUInt32ToEndian(SDAHeader->Salt.saltLongs[0], kPGPLittleEndian, (PGPByte *)&SALT0);
	PGPUInt32ToEndian(SDAHeader->Salt.saltLongs[1], kPGPLittleEndian, (PGPByte *)&SALT1);
			
	sum0 = SALT0 + blockNumber;
	sum1 = SALT1 + blockNumber;
#else /* !WORDS_BIGENDIAN */
	sum0	= SDAHeader->Salt.saltLongs[ 0 ] + blockNumber;
	sum1	= SDAHeader->Salt.saltLongs[ 1 ] + blockNumber;
#endif /* WORDS_BIGENDIAN */

	for (i = 0; i < kBlockSizeInUInt32 - 2; ++i) 
	{
#ifdef WORDS_BIGENDIAN
		PGPUInt32ToEndian(src[i], kPGPLittleEndian, (PGPByte *)&SRC);
		sum1 += SRC;	
#else /* !PGP_BIG_ENDIAN */
		sum1	+= src[i];
#endif /* PGP_BIG_ENDIAN */
		sum0	+= sum1;		// Simple Fletcher checksum of block
	}
	
#ifdef WORDS_BIGENDIAN
	PGPUInt32ToEndian(src[kBlockSizeInUInt32 - 2], kPGPLittleEndian, (PGPByte *)&SRC0);
	PGPUInt32ToEndian(src[kBlockSizeInUInt32 - 1], kPGPLittleEndian, (PGPByte *)&SRC1);

	iv0 = sum0 ^ SRC0;
	iv1 = sum1 ^ SRC1;

	PGPUInt32ToEndian(iv0, kPGPLittleEndian, (PGPByte *)&IV0);
	PGPUInt32ToEndian(iv1, kPGPLittleEndian, (PGPByte *)&IV1);

	iv0 = IV0;
	iv1 = IV1;
	
#else /* !WORDS_BIGENDIAN */
	iv0 = sum0 ^ src[ kBlockSizeInUInt32 - 2 ];
	iv1 = sum1 ^ src[ kBlockSizeInUInt32 - 1 ];
#endif /* WORDS_BIGENDIAN */

	CAST5encryptCFBdbl(CASTContext, iv0, iv1, ~iv0,
			~iv1, src, dest, kBlockSize / ( 8 + 8) );

#ifdef WORDS_BIGENDIAN
	PGPUInt32ToEndian(sum0, kPGPLittleEndian, (PGPByte *)&SUM0);
	PGPUInt32ToEndian(sum1, kPGPLittleEndian, (PGPByte *)&SUM1);
	sum0 = SUM0;
	sum1 = SUM1;
#endif /* WORDS_BIGENDIAN */

	dest[ kBlockSizeInUInt32 - 2 ] ^= sum0;
	dest[ kBlockSizeInUInt32 - 1 ] ^= sum1;

}
#endif // IS_SEA

char *SDAJustFile(char *filename)													 {

	char *p;

	p = strrchr(filename, '\\');

	if(p!=0)
		return (p+1);
	else
		return filename;
}

#ifdef E_BUSINESS_SERVER
#ifdef WIN32
#define	DIRSEP		"\\"
#else /* !WIN32 */
#define DIRSEP		"/"
#endif /* WIN32 */
#endif /* E_BUSINESS_SERVER */

// getc_buffer feeds characters into the compression
// engine
int comp_getc_buffer(void *pUserInfo)
{
	int c;
	GETPUTINFO *gpi;
	PGPError err;
	SDAEvent Event;
#ifdef WORDS_BIGENDIAN
#ifndef NO_64INT
	static PGPUInt64 fileSize = 0;
#else /* NO_64INT */
	static fileSize = 0;
#endif /* !NO_64INT */
#endif /* WORDS_BIGENDIAN */
#ifdef PGP_UNIX
	static PGPBoolean bFirst = TRUE;
#endif /* PGP_UNIX */

	err=kPGPError_NoErr;

	gpi=(GETPUTINFO *)pUserInfo;

	if(IsPGPError(gpi->err))
		return EOF;

	if(gpi->bFeedFilename)
	{
		if(gpi->fl==NULL)
			return EOF;

#ifdef E_BUSINESS_SERVER
		/*	Drop off leading dir separator */
		{
			char		szRelPath[256] = {'\0'},
						*pszTemp = NULL;
			sprintf(szRelPath, "..%c", DIRSEP[0]);

			if(gpi->bPreserveDirectories)
			{
				char		*pszRel = strstr(gpi->fl->name, szRelPath);
#ifdef WIN32
				char		*pszHead = strstr(gpi->fl->name, ":");
				if(pszHead)
				{
					gpi->PathHead = pszHead - gpi->fl->name + 2;
				}
				else if(gpi->fl->name[0] == DIRSEP[0])
				{
					gpi->PathHead = 1;
				}
				else if(pszRel)
				{
					pszTemp = pszRel;
					while(pszTemp != NULL)
					{
						pszRel = pszTemp + strlen(szRelPath);
						pszTemp = strstr(pszRel, szRelPath);
					}

					gpi->PathHead = pszRel - gpi->fl->name;
				}
				else
				{
					gpi->PathHead = 0;
				}
#else /* !WIN32 */
				if(gpi->fl->name[0] == DIRSEP[0])
					gpi->PathHead = 1;
				else if(pszRel)
				{
					pszTemp = pszRel;
					while(pszTemp != NULL)
					{
						pszRel = pszTemp + strlen(szRelPath);
						pszTemp = strstr(pszRel, szRelPath);
					}

					gpi->PathHead = pszRel - gpi->fl->name;
				}
				else
					gpi->PathHead = 0;
#endif /* WIN32 */
			}
			else
			{
				char		*pszFilename = strrchr(gpi->fl->name, DIRSEP[0]);
				if(pszFilename)
				{
					gpi->PathHead = pszFilename + 1 - gpi->fl->name;
				}
				else
				{
					gpi->PathHead = 0;
				}
			}
		}
#endif /* E_BUSINESS_SERVER */

		// Generate New File
		if(gpi->FeedIndex==0)
		{
#ifdef NO_64INT 
			gpi->SDAHeader->NumFiles[0]++;
#else /* !NO_64INT */
			gpi->SDAHeader->NumFiles++;
#endif /* NO_64INT */

			strcpy(gpi->FileName,SDAJustFile(gpi->fl->name));

			Event.type=kSDAEvent_NewFileEvent;
			Event.data.newfileData.fileName=gpi->fl->name;

			err=(gpi->UserProc)(gpi->context,&Event,gpi->pUserValue);

			if(IsPGPError(err))
			{
				gpi->err=err;
				// Trick the encryptor engine here. We'll delete
				// the file later
				return EOF;
			}

			if(gpi->fl->IsDirectory)
			{
				gpi->FileSize=PGPSDA_SIZEDIRECTORY;
			}
			else
			{
#ifdef WIN32
				struct _stati64 buf;
				_stati64(gpi->fl->name, &buf );
#else /* !WIN32 */
#ifdef NO_64INT
				struct stat buf;
				stat(gpi->fl->name, &buf);
#else /* !NO_64INT */
				struct stat64 buf;
				stat64(gpi->fl->name, &buf);
#endif /* NO_64INT */
#endif /* WIN32 */

#ifdef WORDS_BIGENDIAN
				fileSize = buf.st_size;
#ifndef NO_64INT 
				PGPUInt64ToLittleEndian(fileSize, (PGPByte *)&gpi->FileSize);
#else /* NO_64INT */
				PGPUInt32ToEndian(fileSize, kPGPLittleEndian, (PGPByte *)&gpi->FileSize);
#endif /* !NO_64INT */ 
#else /* !WORDS_BIGENDIAN */
				gpi->FileSize=buf.st_size;
#endif /* WORDS_BIGENDIAN */

#ifdef WIN32
				gpi->fin=fopen(gpi->fl->name,"rb");
#else /* !WIN32 */
#ifdef NO_64INT
				gpi->fin=fopen(gpi->fl->name,"rb");
#else /* !NO_64INT */
				gpi->fin=fopen64(gpi->fl->name, "rb");
#endif /* NO_64INT */
#endif /* WIN32 */
				if(gpi->fin==0)
				{
					// Couldn't open the file. Maybe a better error
					// here for cross platform?

					gpi->err=kPGPError_FileOpFailed;

					Event.type=kSDAEvent_ErrorEvent;
					Event.data.errorData.fileName=gpi->fl->name;
					Event.data.errorData.err=gpi->err;

					err=(gpi->UserProc)(NULL,&Event,gpi->pUserValue);

					// Trick the encryptor engine here. We'll delete
					// the file later
					return EOF;
				}

				gpi->FileIndex=0;
			}
		}

		// Feed in the File Size
#ifdef NO_64INT 
		if(gpi->FeedIndex<sizeof(PGPUInt32))
		{
			c=(unsigned char)((char *)&(gpi->FileSize))[gpi->FeedIndex];
			gpi->FeedIndex++;
			return c;
		}
		/* Write out another 32 bits of data here */
		else if((gpi->FeedIndex >= sizeof(PGPUInt32)) &&
				(gpi->FeedIndex < (sizeof(PGPUInt32) * 2)))
		{
			/*	Check to see if this is a directory, if yes, output a 0xFFFFFFFF */
			if(gpi->FileSize == PGPSDA_SIZEDIRECTORY)
				c = 255;
			else
				c = (char)'\0';
			gpi->FeedIndex++;
			return c;
		}
#else /* !NO_64INT */
		if(gpi->FeedIndex<sizeof(PGPUInt64))
		{
			c=(unsigned char)((char *)&(gpi->FileSize))[gpi->FeedIndex];
			gpi->FeedIndex++;
			return c;
		}
#endif /* NO_64INT */

#ifdef WORDS_BIGENDIAN
#ifdef NO_64INT
		if(gpi->FeedIndex == (sizeof(PGPUInt32) * 2))
#else /* !NO_64INT */
		if(gpi->FeedIndex == sizeof(PGPUInt64))
#endif /* NO_64INT */
			gpi->FileSize = fileSize;
#endif /* WORDS_BIGENDIAN */

		// Feed in the File Name
#ifdef PGP_UNIX
		/*	Drop leading '/'*/
		if(bFirst)
		{
#ifdef NO_64INT
			if(gpi->fl->name[gpi->PathHead+gpi->FeedIndex-(sizeof(PGPUInt32) * 2)] == '/')
#else /* !NO_64INT */
			if(gpi->fl->name[gpi->PathHead+gpi->FeedIndex-sizeof(PGPUInt64)] == '/')
#endif /* NO_64INT */
			gpi->FeedIndex++;
			bFirst = FALSE;
		}
#endif /* PGP_UNIX */

#ifdef NO_64INT
		c=gpi->fl->name[gpi->PathHead+gpi->FeedIndex-(sizeof(PGPUInt32)*2)];
#else /* !NO_64INT */
		c=gpi->fl->name[gpi->PathHead+gpi->FeedIndex-sizeof(PGPUInt64)];
#endif /* NO_64INT */
		gpi->FeedIndex++;

#ifdef PGP_UNIX
		/*	Change directory separator to that for Win32 */
		if(c == '/')
			c = '\\';
#endif /* PGP_UNIX */

		if(c==0)
		{
			// If directory or empty just repeat for next
			if((gpi->fl->IsDirectory)||(gpi->FileSize==0))
			{
				if(gpi->FileSize==0)
				{
					// Also close it down as well
					fclose(gpi->fin);
					gpi->fin=0;
				}

				gpi->bFeedFilename=TRUE;
			}
			else
			{
				gpi->bFeedFilename=FALSE;
			}
#ifdef PGP_UNIX
			bFirst=TRUE;
#endif /* PGP_UNIX */
			gpi->FeedIndex=0;
			gpi->fl=gpi->fl->next;
		}

		return c;
	}

	// Feed in the File!
	c=fgetc(gpi->fin);
	gpi->FileIndex++;

	if(gpi->FileIndex%512==0)
	{
		Event.type=kSDAEvent_ProgressEvent;
		Event.data.progressData.bytesWritten=gpi->FileIndex;
		Event.data.progressData.bytesTotal=gpi->FileSize;

		err=(gpi->UserProc)(gpi->context,&Event,gpi->pUserValue);

		if(IsPGPError(err))
		{
			gpi->err=err;
			// Trick the encryptor engine here. We'll delete
			// the file later
			return EOF;
		}
	}

	if(gpi->FileIndex==gpi->FileSize)
	{
		fclose(gpi->fin);
		gpi->fin=0;
		gpi->bFeedFilename=TRUE;

		// We're done, so update progress
		Event.type=kSDAEvent_ProgressEvent;
		Event.data.progressData.bytesWritten=gpi->FileIndex;
		Event.data.progressData.bytesTotal=gpi->FileSize;

		err=(gpi->UserProc)(gpi->context,&Event,gpi->pUserValue);

		if(IsPGPError(err))
		{
			gpi->err=err;
			// Trick the encryptor engine here. We'll delete
			// the file later
			return EOF;
		}
	}

	return c;
}

// find if iPstr2 is in iPstr1
// case doesn't matter
// return is same as strstr 
char *mystrstri(char *iPstr1, char *iPstr2)
{            
	int i;
	int Len    = strlen(iPstr2);
	int MaxLen = strlen(iPstr1)-Len;
  
	for(i=0; i<=MaxLen; i++)
	{
		if(!strnicmp(iPstr1+i, iPstr2, Len)) 
			break;
	}

	if(i>MaxLen) 
		return NULL;

	return (iPstr1+i);
}

// putc_buffer takes output from compression engine,
// encodes it, and writes it to disk
int comp_putc_buffer(int invoer,void *pUserInfo)
{
	GETPUTINFO *gpi;

	gpi=(GETPUTINFO *)pUserInfo;

⌨️ 快捷键说明

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