📄 pgpsdacreate.c
字号:
/*__________________________________________________________________________
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 + -