📄 pgpfileref.c
字号:
error:
if (*tempFileRef != NULL)
{
PFLFreeFileSpec(*tempFileRef);
*tempFileRef = NULL;
}
if (errorCode != NULL)
{
pgpAssertAddrValid(errorCode, PGPError);
*errorCode = err;
}
return NULL;
}
#endif /* ] PGP_MACINTOSH */
/*____________________________________________________________________________
A stupid API routine called in several places by one file.
Get RID OF IT as soon as possible.
- the file is renamed to have the name found in "newRef". The rest of
the path is ignored (so why pass it?)
- you can't change either file ref
____________________________________________________________________________*/
PGPError
pgpRenameFile(
PFLConstFileSpecRef oldRef,
PFLConstFileSpecRef newRef)
{
PGPError err = kPGPError_NoErr;
char * newName = NULL;
PFLValidateFileSpec( oldRef );
PFLValidateFileSpec( newRef );
err = PFLGetFileSpecName( newRef, &newName);
if ( IsntPGPError( err ) )
{
PFLFileSpecRef tempRef;
/* need to copy it because PFLFileSpecRename() changes the name
as well as renaming the file */
err = PFLCopyFileSpec( oldRef, &tempRef );
if ( IsntPGPError( err ) )
{
err = PFLFileSpecRename( tempRef, newName );
(void)PFLFreeFileSpec( tempRef );
}
PGPFreeData( newName );
}
return err;
}
PGPFile *
pgpFileRefOpen(
PGPContextRef context,
PFLConstFileSpecRef fileRef,
PGPFileOpenFlags flags,
PGPFileType fileType,
PGPError * errorCode)
{
FILE * stdIOFile;
PGPMemoryMgrRef memoryMgr;
pgpAssertAddrValid( fileRef, PFLFileSpecRef );
memoryMgr = PFLGetFileSpecMemoryMgr( fileRef );
#if PGP_MACINTOSH /* [ */
switch (flags & (kPGPFileOpenReadWritePerm |
kPGPFileOpenAppend | kPGPFileOpenTruncate |
kPGPFileOpenCreate | kPGPFileOpenTextMode))
{
case kPGPFileOpenReadPerm:
return pgpFileRefMacReadOpen( context, fileRef, flags, errorCode);
case kPGPFileOpenStdWriteFlags:
return pgpFileRefMacWriteOpen( context, fileRef, fileType, flags,
errorCode);
default:
break;
}
pgpAssertMsg((flags & (kPGPFileOpenMaybeLocalEncode |
kPGPFileOpenForceLocalEncode)) == 0,
"This combination of flags not currently supported");
#endif /* ] PGP_MACINTOSH */
*errorCode = pgpFileRefStdIOOpen(fileRef, flags, fileType, &stdIOFile);
if ( IsPGPError( *errorCode ) )
return NULL;
switch (flags & kPGPFileOpenReadWritePerm)
{
case kPGPFileOpenReadPerm:
return pgpFileReadOpen( context, stdIOFile, NULL, NULL);
case kPGPFileOpenWritePerm:
return pgpFileWriteOpen( context, stdIOFile, NULL);
default:
pgpAssertMsg(0, "No support for simultaneous read/write yet");
break;
}
fclose(stdIOFile);
return NULL;
}
PGPFileRead *
pgpFileRefReadCreate(
PGPContextRef context,
PFLConstFileSpecRef fileRef,
PGPFileOpenFlags flags,
PGPError * errorCode,
PGPFileDataType * fileDataType)
{
PGPFile * pgpFile;
PGPFileRead * pgpFileRead;
*fileDataType = kPGPFileDataType_Unknown;
if ((pgpFile = pgpFileRefOpen( context, fileRef, flags,
kPGPFileTypeNone, errorCode)) == NULL)
return NULL;
pgpFileRead = pgpPGPFileReadCreate( context, pgpFile, TRUE);
if ( pgpFileRead == NULL)
{
pgpFileClose(pgpFile);
return NULL;
}
*fileDataType = pgpFile->dataType;
return pgpFileRead;
}
/* XXX Compatibility routines follow, intended to be phased out */
/*
* pgpFileRefStdIOOpen is currently the heart of the implementation
* for opening files, but this may change later.
*/
PGPError
pgpFileRefStdIOOpen(
PFLConstFileSpecRef fileRef,
PGPFileOpenFlags flags,
PGPFileType fileType,
FILE ** outFile )
{
char mode[5];
FILE * stdIOFile = NULL;
PGPError err = kPGPError_NoErr;
const char * kModeStr = NULL;
(void)fileType;
#if PGP_DEBUG
if (flags & kPGPFileOpenCreate)
pgpa(pgpaPGPFileTypeValid(fileType));
#endif
*outFile = NULL;
switch (flags & ~(kPGPFileOpenTextMode |
kPGPFileOpenMaybeLocalEncode |
kPGPFileOpenForceLocalEncode |
kPGPFileOpenLocalEncodeHashOnly |
kPGPFileOpenNoMacBinCRCOkay |
kPGPFileOpenLockFile))
{
case kPGPFileOpenReadPerm: kModeStr = "r"; break;
case kPGPFileOpenStdWriteFlags: kModeStr = "w"; break;
case kPGPFileOpenStdAppendFlags:kModeStr = "a"; break;
case kPGPFileOpenReadWritePerm: kModeStr = "r+"; break;
case kPGPFileOpenStdUpdateFlags:kModeStr = "w+"; break;
case kPGPFileOpenStdAppendFlags | kPGPFileOpenReadPerm:
kModeStr = "a+"; break;
default:
pgpAssertMsg(0, "Unsupported open mode");
err = kPGPError_BadParams;
goto error;
}
strcpy( mode, kModeStr );
if (!(flags & kPGPFileOpenTextMode))
strcat(mode, "b");
#if PGP_WIN32
strcat (mode, "c"); /* Commit-to-disk mode, flushes writes out */
#endif
#if PGP_MACINTOSH /* [ */
{
FSSpec spec;
short refNum;
SInt8 perm = fsRdPerm;
err = PFLGetFSSpecFromFileSpec(fileRef, &spec);
if ( IsntPGPError( err ) )
{
OSErr macErr;
if (flags & kPGPFileOpenCreate)
{
macErr = FSpCreate( &spec,
pgpGetMacFileCreatorFromPGPFileType( fileType ),
pgpGetMacFileTypeFromPGPFileType( fileType ),
smSystemScript );
if (macErr != noErr && macErr != dupFNErr)
{
err = pgpErrorFromMacError(macErr,
kPGPError_CantOpenFile);
goto error;
}
}
switch (flags & kPGPFileOpenReadWritePerm)
{
case kPGPFileOpenReadPerm: perm = fsRdPerm; break;
case kPGPFileOpenWritePerm: perm = fsWrPerm; break;
case kPGPFileOpenReadWritePerm: perm = fsRdWrPerm; break;
default:
pgpAssertMsg(0, "Unsupported open mode");
err = kPGPError_BadParams;
goto error;
}
if ((macErr = FSpOpenDF(&spec, perm, &refNum)) != noErr)
{
err = pgpErrorFromMacError(macErr, kPGPError_CantOpenFile);
goto error;
}
stdIOFile = fdopen(refNum, mode);
if (stdIOFile == NULL)
FSClose(refNum);
}
}
#elif PGP_WIN32 /* ] [ */
{
char * fullPath = NULL;
int fileHandle = -1;
int oFlags = 0;
#if HAVE_SHARE_H
int shFlags = 0;
#endif
err = PFLGetFullPathFromFileSpec(fileRef, &fullPath);
if ( IsntPGPError( err ) )
{
/* 'kPGPFileOpenReadWritePerm' is a mask */
if ( ( flags & kPGPFileOpenReadWritePerm ) ==
kPGPFileOpenReadWritePerm )
oFlags |= _O_RDWR;
else if ( flags & kPGPFileOpenReadPerm )
oFlags |= _O_RDONLY;
else if ( flags & kPGPFileOpenWritePerm )
oFlags |= _O_WRONLY;
if ( flags & kPGPFileOpenAppend )
oFlags |= _O_APPEND;
if ( flags & kPGPFileOpenTruncate )
oFlags |= _O_TRUNC;
if ( flags & kPGPFileOpenCreate )
oFlags |= _O_CREAT;
if ( flags & kPGPFileOpenTextMode )
oFlags |= _O_TEXT;
else
oFlags |= _O_BINARY;
/*
* XXX: In the future, we may decide to lock by default,
* but for now we're playing it safe and keeping the
* existing behavior.
*/
#if HAVE_SHARE_H
if ( !( flags & kPGPFileOpenLockFile ) )
shFlags |= _SH_DENYNO;
else if ( flags & kPGPFileOpenWritePerm )
shFlags |= _SH_DENYRW;
else
shFlags |= _SH_DENYWR;
fileHandle = sopen( fullPath, oFlags, shFlags,
_S_IREAD | _S_IWRITE );
#else
fileHandle = open( fullPath, oFlags, _S_IREAD | _S_IWRITE );
#endif
/* Free the path buffer regardless */
PGPFreeData( fullPath);
/* Check for error in sopen */
if ( fileHandle == -1 )
{
if ( errno == EACCES )
err = kPGPError_FilePermissions;
else if ( errno == ENOENT )
err = kPGPError_FileNotFound;
else
err = kPGPError_CantOpenFile;
goto error;
}
stdIOFile = fdopen( fileHandle, mode );
if (stdIOFile == NULL)
goto error;
}
}
#else /* ] [ */
{
char * fullPath = NULL;
#if PGP_UNIX
mode_t oldMask;
#endif
err = PFLGetFullPathFromFileSpec(fileRef, &fullPath);
if ( IsntPGPError( err ) )
{
#if PGP_UNIX
oldMask = umask(sUnixFileTypeTable[fileType].mask);
#endif
stdIOFile = fopen(fullPath, mode);
/* Free the path buffer regardless */
PGPFreeData( fullPath );
if (stdIOFile == NULL)
{
if (errno == EACCES
#ifdef EROFS
|| errno == EROFS
#endif
)
{
err = kPGPError_FilePermissions;
}
else if (errno == ENOENT)
{
err = kPGPError_FileNotFound;
}
else
{
err = kPGPError_CantOpenFile;
}
}
#if PGP_UNIX
umask(oldMask);
#endif
if (stdIOFile == NULL)
goto error;
}
}
#endif /* ] PGP_MACINTOSH */
if ( IsntNull( stdIOFile ) && ( flags & kPGPFileOpenLockFile ) )
{
err = PFLLockFILE( stdIOFile,
( kPFLFileOpenFlags_LockFile |
( ( flags & kPGPFileOpenWritePerm )
? kPFLFileOpenFlags_ReadWrite
: kPFLFileOpenFlags_ReadOnly ) ) );
if ( IsPGPError( err ) )
{
fclose( stdIOFile );
stdIOFile = NULL;
}
}
error:
if ( IsNull( stdIOFile ) || IsPGPError( err ) )
{
if ( IsntPGPError( err ) )
err = kPGPError_CantOpenFile;
}
*outFile = stdIOFile;
/* we should have an error and no file, or no error and a file */
pgpAssert( ( IsntPGPError( err ) && IsntNull( *outFile ) ) ||
( IsPGPError( err ) && IsNull( *outFile ) ) );
return err;
}
/*
* Due to the way memory is handled on PGP_WIN32 systems with static linking,
* fclose must be called from the same library which called fopen.
* This function servers that purpose. It should be called by external
* libraries and apps to close FILE * handles returned by this module.
*/
PGPError
pgpStdIOClose(
FILE * stdIOFile)
{
if (fclose (stdIOFile)) {
return kPGPError_FileOpFailed;
}
return kPGPError_NoErr;
}
/*
* Local Variables:
* tab-width: 4
* End:
* vi: ts=4 sw=4
* vim: si
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -