📄 pgpfileref.c
字号:
/*____________________________________________________________________________
Copyright (C) 1997 Network Associates Inc. and affiliated companies.
All rights reserved.
$Id: pgpFileRef.c,v 1.76 1999/03/10 02:50:30 heller Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_PATHS_H
#include <paths.h>
#endif
#if PGP_UNIX || PGP_WIN32
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#endif
#if __MWERKS__
#define HAVE_SHARE_H 0
#else
#define HAVE_SHARE_H 0
#endif
#if PGP_WIN32
#include <windows.h>
#include <io.h>
#if HAVE_SHARE_H
#include <share.h>
#endif
#endif
#include <errno.h>
#include <stdio.h>
#include <string.h>
#if PGP_MACINTOSH
#include <unix.h>
#include <Errors.h>
#include <Folders.h>
#include <Script.h>
#endif
#include "pgpFileRef.h"
#include "pgpFileNames.h"
#include "pgpFileUtilities.h"
#include "pgpErrors.h"
#include "pgpTypes.h"
#include "pgpDebug.h"
#include "pgpMem.h"
#include "pgpContext.h"
#include "pgpFileSpec.h"
#if PGP_MACINTOSH
#include "MacFiles.h"
#include "MacStrings.h"
#include "pgpMacFile.h"
#include "pgpMacUtils.h"
#endif
#if !defined(_PATH_TMP) && PGP_UNIX && HAVE_MKSTEMP
#define _PATH_TMP "/tmp/"
#endif
#if HAVE_MKSTEMP && defined(sparc)
extern int mkstemp (char *__template);
#endif
#define pgpaPGPFileTypeValid(fileType) \
pgpaAssert(fileType > kPGPFileTypeNone \
&& fileType < kPGPFileTypeNumTypes)
/* These must be kept in sync with the PGPFileType decl in pgpFileRef.h */
#if PGP_UNIX /* [ */
static struct UnixFileTypeEntry
{
mode_t mask; /* umask value for permissions */
} sUnixFileTypeTable[kPGPFileTypeNumTypes] = {
{ 0 }, /* kPGPFileTypeNone */
{ 0077 }, /* kPGPFileTypePrefs */
{ 0077 }, /* kPGPFileTypePubRing */
{ 0077 }, /* kPGPFileTypePrivRing */
{ 0077 }, /* kPGPFileTypeDetachedSig */
{ 0077 }, /* kPGPFileTypeRandomSeed */
{ 0077 }, /* kPGPFileTypeArmorFile */
{ 0077 }, /* kPGPFileTypeEncryptedData */
{ 0077 }, /* kPGPFileTypeGroups */
{ 0077 }, /* kPGPFileTypeDecryptedText */
{ 0077 }, /* kPGPFileTypeDecryptedBin */
{ 0077 }, /* kPGPFileTypeSignedData */
{ 0077 } /* kPGPFileTypeExported509Keys */
};
#endif /* ] PGP_UNIX */
PGPMemoryMgrRef
pgpGetFileRefMemoryMgr( PFLConstFileSpecRef fileRef )
{
return(
PFLGetFileSpecMemoryMgr( (PFLConstFileSpecRef)fileRef ) );
}
/*
* pgpGetFileRefName returns a string allocated with pgpContextMemAlloc(),
* which the caller is responsible for freeing.
*/
char *
pgpGetFileRefName( PFLConstFileSpecRef fileRef)
{
char * name = NULL;
PGPError err = kPGPError_NoErr;
err = PFLGetFileSpecName( fileRef, &name );
return( name );
}
PGPError
pgpSetFileRefName(
PFLFileSpecRef fileRef,
char const * newName)
{
return( PFLSetFileSpecName( fileRef, newName ) );
}
uchar *
pgpExportFileRef(
PFLConstFileSpecRef fileRef,
size_t * size)
{
PGPError err = kPGPError_NoErr;
PGPByte * data = NULL;
PGPSize dataSize;
err = PFLExportFileSpec( fileRef, &data, &dataSize );
*size = dataSize;
return( data );
}
PGPError
pgpImportFileRef(
PGPContextRef context,
uchar const * buffer,
size_t size,
PFLFileSpecRef * outRef )
{
PGPError err = kPGPError_NoErr;
err = PFLImportFileSpec( PGPGetContextMemoryMgr( context ),
buffer, size, outRef );
return( err );
}
#if PGP_MACINTOSH /* [ */
PGPError
pgpCalcFileSize(
PFLConstFileSpecRef fileRef,
PGPFileOpenFlags flags,
size_t * fileSize)
{
return pgpMacCalcFileSize(fileRef, flags, fileSize);
}
PGPError
pgpCreateFile(
PFLConstFileSpecRef fileRef,
PGPFileType fileType)
{
PGPError err = kPGPError_NoErr;
FSSpec spec;
OSErr macErr;
PFLValidateFileSpec( fileRef );
err = PFLGetFSSpecFromFileSpec(fileRef, &spec);
if ( IsntPGPError( err ) )
{
macErr = FSpCreate( &spec,
pgpGetMacFileCreatorFromPGPFileType( fileType ),
pgpGetMacFileTypeFromPGPFileType( fileType ),
smSystemScript );
if (macErr != noErr)
err = pgpErrorFromMacError(macErr, kPGPError_CantOpenFile);
}
return err;
}
FILE *
pgpStdIOOpenTempFile(
PGPContextRef context,
PFLFileSpecRef * tempFileRef,
PGPError * errorCode)
{
FSSpec spec;
FILE * stdIOFile = NULL;
PGPError err = kPGPError_NoErr;
OSErr macErr;
long i;
pgpa(pgpaAddrValid(tempFileRef, PFLFileSpecRef));
*tempFileRef = NULL;
if ((macErr = FindFolder(kOnSystemDisk, kTemporaryFolderType,
kCreateFolder, &spec.vRefNum,
&spec.parID)) != noErr)
goto macError;
for (i = 0; ; i++)
{
pgpFormatPStr(spec.name, sizeof(spec.name), 0, "PGP Temp %d", i);
macErr = FSpCreate( &spec, '????', 'BINA', smSystemScript );
if (macErr == noErr)
break;
else if (macErr != dupFNErr)
goto macError;
}
err = PFLNewFileSpecFromFSSpec( PGPGetContextMemoryMgr( context ),
&spec, tempFileRef );
if ( IsErr( err ) )
goto error;
*errorCode = pgpFileRefStdIOOpen(*tempFileRef, kPGPFileOpenStdUpdateFlags,
kPGPFileTypeDecryptedBin, &stdIOFile);
return( stdIOFile );
macError:
err = pgpErrorFromMacError(macErr, kPGPError_CantOpenFile);
error:
if (*tempFileRef != NULL)
{
PFLFreeFileSpec(*tempFileRef);
*tempFileRef = NULL;
}
if (errorCode != NULL)
{
pgpAssertAddrValid(errorCode, PGPError);
*errorCode = err;
}
return NULL;
}
#else /* ] PGP_MACINTOSH [ */
PGPError
pgpCalcFileSize(
PFLConstFileSpecRef fileRef,
PGPFileOpenFlags flags,
size_t * fileSize)
{
PGPError err = kPGPError_NoErr;
char * fullPath = NULL;
struct stat statBuf;
PFLValidateFileSpec( fileRef );
PGPValidatePtr( fileSize );
(void)flags; /* Avoid warning */
*fileSize = 0; /* In case there's an error */
err = PFLGetFullPathFromFileSpec(fileRef, &fullPath);
if ( IsntPGPError( err ) )
{
/* XXX Maybe make this more portable. Does this work on MSDOS? */
if (stat(fullPath, &statBuf) != 0)
err = kPGPError_CantOpenFile;
else if ((S_IFMT & statBuf.st_mode) == S_IFREG)
*fileSize = statBuf.st_size;
/* XXX Maybe return a special err if it's not a regular file */
}
PGPFreeData( fullPath );
return err;
}
PGPError
pgpCreateFile(
PFLConstFileSpecRef fileRef,
PGPFileType fileType)
{
PGPError err = kPGPError_NoErr;
char * fullPath = NULL;
PFLValidateFileSpec( fileRef );
(void)fileType;
err = PFLGetFullPathFromFileSpec(fileRef, &fullPath);
if ( IsntPGPError( err ) )
{
#if PGP_UNIX /* [ */
int fileDes;
/*
* XXX Beware that calling this routine could be a security flaw,
* because there is a window between creating and opening
* the file, in between which the file might have been moved
* out of the way, thus possibly having you open a new file
* with the wrong permissions.
*/
fileDes = open(fullPath,
O_WRONLY | O_CREAT | O_EXCL,
0666 & ~sUnixFileTypeTable[fileType].mask);
if (fileDes > 0)
close(fileDes);
else
err = kPGPError_CantOpenFile; /* XXX Use better error */
#else /* ] PGP_UNIX [ */
FILE * stdIOFile;
stdIOFile = fopen(fullPath, "ab+");
if (stdIOFile != NULL)
fclose(stdIOFile);
else
err = kPGPError_CantOpenFile; /* XXX Use better error */
#endif /* ] PGP_UNIX */
}
PGPFreeData( fullPath);
return err;
}
FILE *
pgpStdIOOpenTempFile(
PGPContextRef context,
PFLFileSpecRef * tempFileRef,
PGPError * errorCode)
{
char fileName[L_tmpnam];
PGPError err = kPGPError_NoErr;
FILE * stdIOFile = NULL;
pgpa(pgpaAddrValid(tempFileRef, PFLFileSpecRef));
*tempFileRef = NULL;
#if defined(_PATH_TMP) && HAVE_MKSTEMP /* [ */
{
int fd = -1;
strncpy(fileName, _PATH_TMP "ptmpXXXXXX", sizeof(fileName));
fileName[sizeof(fileName) - 1] = '\0';
if ((fd = mkstemp(fileName)) == -1 ||
(stdIOFile = fdopen(fd, "w+b")) == NULL)
{
if (fd != -1)
close(fd);
goto fileError;
}
err = PFLNewFileSpecFromFullPath( PGPGetContextMemoryMgr( context ),
fileName, tempFileRef);
if (IsPGPError( err ))
goto error;
}
#else /* ] defined(_PATH_TMP) && HAVE_MKSTEMP [ */
if (tmpnam(fileName) != fileName)
goto fileError;
if (IsPGPError(err = PFLNewFileSpecFromFullPath(
PGPGetContextMemoryMgr( context ), fileName, tempFileRef)))
{
err = kPGPError_OutOfMemory;
goto error;
}
/* XXX Perhaps check for an error and retry if necessary */
*errorCode = pgpFileRefStdIOOpen(*tempFileRef,
kPGPFileOpenStdUpdateFlags,
kPGPFileTypeDecryptedBin, &stdIOFile);
#endif /* ] defined(_PATH_TMP) && HAVE_MKSTEMP */
if (stdIOFile == NULL)
{
fileError:
err = kPGPError_CantOpenFile;
goto error;
}
return stdIOFile;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -