📄 pgpfileref.c
字号:
{
pgpCopyMemory(fileRef, externFileRef, externSize);
externFileRef->magic = kPGPExternalFileRefMagic;
*size = externSize;
}
break;
#if MACINTOSH /* [ */
case kPGPFileRefMacV1:
{
FSSpec const * spec;
uchar volumeName[256];
HVolumeParam pb;
spec = pgpFileRefData(fileRef, FSSpec);
pb.ioNamePtr = volumeName;
pb.ioVRefNum = spec->vRefNum;
pb.ioVolIndex = 0;
if (PBHGetVInfoSync((HParmBlkPtr)&pb) == noErr)
{
externSize = fileRef->size + volumeName[0] + 1;
externFileRef = (PGPFileRef *)pgpAlloc(externSize);
if (externFileRef != NULL)
{
pgpCopyMemory(fileRef, externFileRef, fileRef->size);
pgpCopyMemory(volumeName,
(uchar *)externFileRef + fileRef->size,
volumeName[0] + 1);
externFileRef->magic = kPGPExternalFileRefMagic;
*size = externSize;
}
}
break;
}
#endif /* ] MACINTOSH */
default:
pgpAssertMsg(0, "Unsupported PGPFileRef type");
break;
}
return (uchar *)externFileRef;
}
PGPFileRef *
pgpImportFileRef(
uchar const * buffer,
size_t size)
{
PGPFileRef * fileRef;
pgpa(pgpaAddrValid(buffer, uchar));
fileRef = (PGPFileRef *)pgpAlloc(size);
if (fileRef != NULL)
{
pgpCopyMemory(buffer, fileRef, size);
if (size < sizeof(PGPFileRef) ||
fileRef->magic != kPGPExternalFileRefMagic ||
fileRef->size > size)
{
pgpFree(fileRef);
return NULL;
}
fileRef->magic = kPGPFileRefMagic;
pgpa(pgpaPGPFileRefValid(fileRef));
/*
* XXX In the future if PGPFileRefs contain pointers,
* this will need to be changed.
*/
switch (fileRef->type)
{
case kPGPFileRefFullPath:
break;
#if MACINTOSH /* [ */
case kPGPFileRefMacV1:
{
FSSpec * spec;
uchar volumeName[256];
uchar * storedVolName;
HVolumeParam pb;
spec = pgpFileRefData(fileRef, FSSpec);
storedVolName = (uchar *)(spec + 1);
pgpAssert(size >= sizeof(PGPFileRef) +
sizeof(FSSpec) +
storedVolName[0] + 1);
/*
* Check to see if the vRefNum stored in the
* fileRef has the correct volume name.
*/
pb.ioNamePtr = volumeName;
pb.ioVRefNum = spec->vRefNum;
pb.ioVolIndex = 0;
if (PBHGetVInfoSync((HParmBlkPtr)&pb) != noErr ||
!PStringsAreEqual(volumeName, storedVolName))
{
/*
* The volume name didn't match. Try to look up
* the vRefNum from the volume name.
*/
CopyPString(storedVolName, volumeName);
volumeName[++volumeName[0]] = ':';
pb.ioNamePtr = volumeName;
pb.ioVRefNum = -1;
pb.ioVolIndex = -1;
if (PBHGetVInfoSync((HParmBlkPtr)&pb) != noErr ||
!PStringsAreEqual(volumeName, storedVolName))
{
/*
* It couldn't find the volume by name. If
* it used to be the boot volume (vRefNum == -1),
* use the current boot volume. Otherwise, fail.
*/
if (spec->vRefNum != -1)
{
pgpFree(fileRef);
return NULL;
}
}
else
spec->vRefNum = pb.ioVRefNum;
}
break;
}
#endif /* ] MACINTOSH */
default:
pgpAssertMsg(0, "Unsupported PGPFileRef type");
pgpFree(fileRef);
return NULL;
}
}
if (fileRef != NULL)
pgpRealloc((void **)&fileRef, fileRef->size);
return fileRef;
}
#if MACINTOSH /* [ */
PGPError
pgpCalcFileSize(
PGPFileRef const * fileRef,
PGPFileOpenFlags flags,
size_t * fileSize)
{
return pgpMacCalcFileSize(fileRef, flags, fileSize);
}
PGPError
pgpCreateFile(
PGPFileRef const * fileRef,
PGPFileType fileType)
{
PGPError result = PGPERR_OK;
OSErr macResult;
FSSpec spec;
pgpa((
pgpaPGPFileRefValid(fileRef),
pgpaPGPFileTypeValid(fileType)));
if ((result = pgpFSSpecFromFileRef(fileRef, &spec)) == PGPERR_OK)
{
if ((macResult = HCreate(spec.vRefNum, spec.parID, spec.name,
sMacFileTypeTable[fileType].creator,
sMacFileTypeTable[fileType].type)) != noErr)
result = pgpErrorFromMacError(macResult, PGPERR_NO_FILE);
}
return result;
}
PGPError
pgpDeleteFile(
PGPFileRef const * fileRef)
{
PGPError result = PGPERR_OK;
OSErr macResult;
FSSpec spec;
pgpa(pgpaPGPFileRefValid(fileRef));
if ((result = pgpFSSpecFromFileRef(fileRef, &spec)) == PGPERR_OK)
{
if ((macResult = HDelete(spec.vRefNum, spec.parID,
spec.name)) != noErr)
result = pgpErrorFromMacError(macResult, PGPERR_NO_FILE);
}
return result;
}
PGPError
pgpRenameFile(
PGPFileRef const * oldRef,
PGPFileRef const * newRef)
{
PGPError result = PGPERR_OK;
OSErr macResult;
FSSpec oldSpec;
FSSpec newSpec;
pgpa((
pgpaPGPFileRefValid(oldRef),
pgpaPGPFileRefValid(newRef),
pgpaAssert(oldRef->type == newRef->type)));
if ((result = pgpFSSpecFromFileRef(oldRef, &oldSpec)) == PGPERR_OK &&
(result = pgpFSSpecFromFileRef(newRef, &newSpec)) == PGPERR_OK)
{
pgpAssert(oldSpec.vRefNum == newSpec.vRefNum &&
oldSpec.parID == newSpec.parID);
if ((macResult = HRename(oldSpec.vRefNum, oldSpec.parID,
oldSpec.name, newSpec.name)) != noErr)
result = pgpErrorFromMacError(macResult, PGPERR_NO_FILE);
}
return result;
}
FILE *
pgpStdIOOpenTempFile(
PGPFileRef ** tempFileRef,
PGPError * errorCode)
{
FSSpec spec;
FILE * stdIOFile = NULL;
PGPError result = PGPERR_OK;
OSErr macResult;
long i;
pgpa(pgpaAddrValid(tempFileRef, PGPFileRef *));
*tempFileRef = NULL;
if ((macResult = 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);
macResult = HCreate(spec.vRefNum, spec.parID, spec.name,
'????', 'BINA');
if (macResult == noErr)
break;
else if (macResult != dupFNErr)
goto macError;
}
if ((*tempFileRef = pgpNewFileRefFromFSSpec(&spec)) == NULL)
{
result = PGPERR_NOMEM;
goto error;
}
return pgpFileRefStdIOOpen(*tempFileRef, kPGPFileOpenStdUpdateFlags,
kPGPFileTypeDecryptedBin, errorCode);
macError:
result = pgpErrorFromMacError(macResult, PGPERR_NO_FILE);
error:
if (*tempFileRef != NULL)
{
pgpFreeFileRef(*tempFileRef);
*tempFileRef = NULL;
}
if (errorCode != NULL)
{
pgpAssertAddrValid(errorCode, PGPError);
*errorCode = result;
}
return NULL;
}
#else /* ] MACINTOSH [ */
PGPError
pgpCalcFileSize(
PGPFileRef const * fileRef,
PGPFileOpenFlags flags,
size_t * fileSize)
{
PGPError result = PGPERR_OK;
char * fullPath = NULL;
struct stat statBuf;
pgpa((
pgpaPGPFileRefValid(fileRef),
pgpaAddrValid(fileSize, size_t)));
(void)flags; /* Avoid warning */
*fileSize = 0; /* In case there's an error */
if ((result = pgpFullPathFromFileRef(fileRef, &fullPath)) == PGPERR_OK)
{
/* XXX Maybe make this more portable. Does this work on MSDOS? */
if (stat(fullPath, &statBuf) != 0)
result = PGPERR_NO_FILE;
else if ((S_IFMT & statBuf.st_mode) == S_IFREG)
*fileSize = statBuf.st_size;
/* XXX Maybe return a special result if it's not a regular file */
}
pgpMemFree(fullPath);
return result;
}
PGPError
pgpCreateFile(
PGPFileRef const * fileRef,
PGPFileType fileType)
{
PGPError result = PGPERR_OK;
char * fullPath = NULL;
pgpa((
pgpaPGPFileRefValid(fileRef),
pgpaPGPFileTypeValid(fileType)));
if ((result = pgpFullPathFromFileRef(fileRef, &fullPath)) == PGPERR_OK)
{
#if 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,
sUnixFileTypeTable[fileType].mask);
if (fileDes > 0)
close(fileDes);
else
result = PGPERR_NO_FILE; /* XXX Use better error */
#else /* ] UNIX [ */
FILE * stdIOFile;
stdIOFile = fopen(fullPath, "ab+");
if (stdIOFile != NULL)
fclose(stdIOFile);
else
result = PGPERR_NO_FILE; /* XXX Use better error */
#endif /* ] UNIX */
}
pgpMemFree(fullPath);
return result;
}
PGPError
pgpDeleteFile(
PGPFileRef const * fileRef)
{
PGPError result = PGPERR_OK;
char * fullPath = NULL;
pgpa(pgpaPGPFileRefValid(fileRef));
if ((result = pgpFullPathFromFileRef(fileRef, &fullPath)) == PGPERR_OK)
{
if (remove(fullPath) != 0)
result = PGPERR_NO_FILE; /* XXX Use better error */
}
pgpMemFree(fullPath);
return result;
}
PGPError
pgpRenameFile(
PGPFileRef const * oldRef,
PGPFileRef const * newRef)
{
PGPError result = PGPERR_OK;
char * oldPath = NULL;
char * newPath = NULL;
pgpa((
pgpaPGPFileRefValid(oldRef),
pgpaPGPFileRefValid(newRef),
pgpaAssert(oldRef->type == newRef->type)));
if ((result = pgpFullPathFromFileRef(oldRef, &oldPath)) == PGPERR_OK &&
(result = pgpFullPathFromFileRef(newRef, &newPath)) == PGPERR_OK)
{
size_t nameOffset;
nameOffset = pgpFileNameTail(oldPath) - oldPath;
pgpa((
pgpaAssert(newPath + nameOffset == pgpFileNameTail(newPath)),
pgpaAssert(pgpMemoryEqual(oldPath, newPath, nameOffset))));
if (rename(oldPath, newPath) != 0)
result = PGPERR_NO_FILE; /* XXX Improve error */
}
pgpMemFree(oldPath);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -