📄 pgpmacfile.c
字号:
/*
* pgpMacFile.c -- PgpFile implementation for MacBinary translation
*
* Copyright (C) 1997 Pretty Good Privacy, Inc. All rights reserved.
*
* $Id: pgpMacFile.c,v 1.9.2.3 1997/06/07 09:50:08 mhw Exp $
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <stdio.h>
#include "MacStrings.h"
#include "pgpTypes.h"
#include "pgpFile.h"
#include "pgpMacFile.h"
#include "pgpMacUtils.h"
#include "pgpFileRef.h"
#include "pgpFileMod.h"
#include "pgpCFB.h"
#include "pgpMem.h"
#include "pgpErr.h"
#include "pgpUsuals.h"
/* XXX Is this stuff still necessary? */
#define DESKTOP 0x0001 // ---- ---- ---- ---1
#define COLOR 0x000E // ---- ---- ---- 111-
#define INITED 0x0100 // ---- ---1 ---- ----
#define CHANGED 0x0200 // ---- --1- ---- ----
#define BUSY 0x0400 // ---- -1-- ---- ----
#define BOZO 0x0800 // ---- 1--- ---- ----
#define SYSTEM 0x1000 // ---1 ---- ---- ----
#define BUNDLE 0x2000 // --1- ---- ---- ----
#define INVISIBLE 0x4000 // -1-- ---- ---- ----
#define LOCKED 0x8000 // 1--- ---- ---- ----
#define NOMODIFY (DESKTOP | INITED | CHANGED | BUSY)
#pragma options align=mac68k
typedef struct MacBinaryHeader_
{
uchar filler;
uchar oldVersion; /* 000: Must be zero for compatibility */
uchar name[64]; /* 001: Pascal string */
FInfo info1; /* 065: Original Finder info: */
/* File type (long) */
/* File creator (long) */
/* Flags (word, low byte must be zero) */
/* File's location (Point) */
/* File's window (short) */
uchar protectedBit; /* 081: Low order bit */
uchar zero1; /* 082: Must be zero for compatibility */
long dLength; /* 083: Data fork length (in bytes) */
long rLength; /* 087: Resource fork length (in bytes) */
ulong creation; /* 091: Creation date */
ulong modification; /* 095: Modification date */
short getInfoLength; /* 099: Get info length */
uchar info2; /* 101: Finder flags, low byte */
uchar dummy1;
uchar dummy2[18]; /* 103: Not used */
uchar dummy3;
uchar newVersion; /* 122: Uploading program version number */
uchar minimumVersion; /* 123: Minimum version number needed */
uchar crc1;
uchar crc2;
uchar endFiller[2]; /* To pad out to 128 bytes */
} MacBinaryHeader;
#pragma options align=reset
static struct BinaryTypeRec
{
OSType creator;
OSType type;
int length;
uchar * ident;
} smartBinRecs[] = {
{ 'pZIP', 'pZIP', 2, "PK" },
{ 'LZIV', 'ZIVU', 3, "\x1F\x9D\x90" },
{ 'MIDI', 'Midi', 4, "MThd" },
{ 'PAK ', 'PAK ', 2, "\x1A\x0A" },
{ 'BOOZ', 'ZOO ', 4, "ZOO " },
{ 'JVWR', 'GIFf', 4, "GIF8" },
{ 'SIT!', 'SIT!', 4, "SIT!" },
{ 'CPCT', 'PACT', 2, "\x01\x01" },
{ 'arc*', 'mArc', 2, "\x1A\x08" },
{ 'arc*', 'mArc', 2, "\x1A\x09" },
{ 'JVWR', 'JPEG', 10, "\xFF\xD8\xFF\xE0\0\x10JFIF" },
{ 0, 0, 0, NULL }
};
static OSType nonMacBinaryTypes[] = {
'TEXT', 'pZIP', 'ZIVU', 'Midi', 'PAK ', 'ZOO ', 'GIFf', 'mArc', 'JPEG', 0
};
#define kPGPMacRead 0x01L
#define kPGPMacWrite 0x02L
#define kPGPMacBinMode 0x04L
/* For write mode only: whether we should check */
#define kPGPCheckMacBin 0x08L
/* Strip out volatile information for detached sig */
#define kPGPMacBinHashOnly 0x10L
/* CRC 0 in MacBin header is okay */
#define kPGPNoMacBinCRCOkay 0x20L
/* This is the private data for macfiles */
typedef struct MacFile_
{
ulong flags;
short dataRef, resRef;
long dataOffset, resOffset, totalSize;
long filePos;
PgpFileError err;
PGPError error;
PGPFileRef * fileRef;
PGPFileType fileType;
MacBinaryHeader macBinHeader;
} MacFile;
static PGPError PrepareToWrite(PgpFile *file);
static PGPError SetFileInfo(PgpFile *file);
static void
macSetError(
PgpFile * file,
PGPError code)
{
MacFile * mf = (MacFile *)file->priv;
mf->err.f = file;
mf->err.fpos = mf->filePos;
mf->error = mf->err.error = code;
mf->err.syserrno = 0;
}
static OSErr
macFileReadFork(
PgpFile * file,
short refNum,
long forkOffset,
long forkEnd,
long * sizeLeftPtr,
void ** ptrPtr)
{
MacFile * mf = (MacFile *)file->priv;
long chunkSize;
OSErr result = noErr;
IOParam pb;
if (mf->filePos >= forkOffset &&
(chunkSize = min(*sizeLeftPtr, forkEnd - mf->filePos)) > 0)
{
pb.ioRefNum = refNum;
pb.ioBuffer = (Ptr)*ptrPtr;
pb.ioReqCount = chunkSize;
pb.ioPosMode = fsFromStart;
pb.ioPosOffset = mf->filePos - forkOffset;
result = PBReadSync((ParmBlkPtr)&pb);
mf->filePos += pb.ioActCount;
*(Ptr *)ptrPtr += pb.ioActCount;
*sizeLeftPtr -= pb.ioActCount;
if ((mf->flags & kPGPMacBinMode) && result == eofErr)
{
/*
* Clear any memory which was beyond the EOF. This is expected
* in MacBinary because each fork is padded to a multiple of
* 128-bytes.
*/
chunkSize -= pb.ioActCount;
pgpClearMemory((uchar *)*ptrPtr, chunkSize);
mf->filePos += chunkSize;
*(Ptr *)ptrPtr += chunkSize;
*sizeLeftPtr -= chunkSize;
result = noErr;
}
else if (result != noErr)
macSetError(file, PGPERR_FILE_OPFAIL);
}
return result;
}
static size_t
macFileRead(
void * ptr,
size_t size,
PgpFile * file)
{
MacFile * mf = (MacFile *)file->priv;
long sizeLeft = (long)size;
long chunkSize;
OSErr result = noErr;
pgpAssert(mf->filePos >= 0);
if (!(mf->flags & kPGPMacRead))
{
macSetError(file, PGPERR_FILE_BADOP);
return 0;
}
/* Handle portion in the MacBinary header, if any */
if ((chunkSize = min(sizeLeft, mf->dataOffset - mf->filePos)) > 0)
{
pgpCopyMemory((uchar *)&mf->macBinHeader + 1 + mf->filePos,
ptr, chunkSize);
mf->filePos += chunkSize;
ptr = (void *)((Ptr)ptr + chunkSize);
sizeLeft -= chunkSize;
}
/* Handle portion in the data fork, if any */
if (result == noErr && sizeLeft > 0)
result = macFileReadFork(file, mf->dataRef, mf->dataOffset,
mf->resOffset, &sizeLeft, &ptr);
/*
* Handle zeroing the first 128 bytes of the resource fork,
* but only if kPGPMacBinHashOnly is set.
*/
if (result == noErr
&& (mf->flags & kPGPMacBinMode) && (mf->flags & kPGPMacBinHashOnly)
&& (chunkSize = min(sizeLeft,
min(mf->resOffset + 128, mf->totalSize)
- mf->filePos)) > 0)
{
pgpClearMemory(ptr, chunkSize);
mf->filePos += chunkSize;
ptr = (void *)((Ptr)ptr + chunkSize);
sizeLeft -= chunkSize;
}
/* Handle portion in the resource fork, if any */
if (result == noErr && sizeLeft > 0 && (mf->flags & kPGPMacBinMode))
result = macFileReadFork(file, mf->resRef, mf->resOffset,
mf->totalSize, &sizeLeft, &ptr);
return (size_t)(size - sizeLeft);
}
static OSErr
macFileWriteFork(
PgpFile * file,
short refNum,
long forkOffset,
long forkEnd, /* Ignored unless kPGPMacBinMode flag set */
long forkLen, /* Ignored unless kPGPMacBinMode flag set */
long * sizeLeftPtr,
void const ** ptrPtr)
{
MacFile * mf = (MacFile *)file->priv;
long chunkSize;
OSErr result = noErr;
IOParam pb;
chunkSize = *sizeLeftPtr;
if (mf->flags & kPGPMacBinMode)
chunkSize = min(chunkSize, forkEnd - mf->filePos);
if (mf->filePos >= forkOffset && chunkSize > 0)
{
pb.ioRefNum = refNum;
pb.ioBuffer = (Ptr)*ptrPtr;
pb.ioPosMode = fsFromStart;
pb.ioPosOffset = mf->filePos - forkOffset;
pb.ioReqCount = chunkSize;
if (mf->flags & kPGPMacBinMode)
pb.ioReqCount = min(pb.ioReqCount, forkLen - pb.ioPosOffset);
result = PBWriteSync((ParmBlkPtr)&pb);
mf->filePos += chunkSize;
*(Ptr *)ptrPtr += chunkSize;
*sizeLeftPtr -= chunkSize;
if (result != noErr)
macSetError(file, PGPERR_FILE_OPFAIL);
}
if (mf->totalSize < mf->filePos)
mf->totalSize = mf->filePos;
return result;
}
static size_t
macFileWrite(
void const * ptr,
size_t size,
PgpFile * file)
{
MacFile * mf = (MacFile *)file->priv;
long sizeLeft = (long)size;
long chunkSize;
OSErr result = noErr;
pgpAssert(mf->filePos >= 0);
if (!(mf->flags & kPGPMacWrite))
{
macSetError(file, PGPERR_FILE_BADOP);
return 0;
}
/* Handle portion in the MacBinary header, if any */
if ((chunkSize = min(sizeLeft, mf->dataOffset - mf->filePos)) > 0)
{
pgpAssert(mf->filePos + chunkSize <= 128);
pgpCopyMemory(ptr, (uchar *)&mf->macBinHeader + 1 + mf->filePos,
chunkSize);
mf->filePos += chunkSize;
ptr = (void *)((Ptr)ptr + chunkSize);
sizeLeft -= chunkSize;
if (mf->totalSize < mf->filePos)
mf->totalSize = mf->filePos;
}
/* Handle portion in the data fork, if any */
if (result == noErr && sizeLeft > 0)
{
PrepareToWrite(file);
result = macFileWriteFork(file, mf->dataRef, mf->dataOffset,
mf->resOffset, mf->macBinHeader.dLength,
&sizeLeft, &ptr);
}
/* Handle portion in the resource fork, if any */
if (result == noErr && sizeLeft > 0 && (mf->flags & kPGPMacBinMode))
result = macFileWriteFork(file, mf->resRef, mf->resOffset,
mf->totalSize, mf->macBinHeader.rLength,
&sizeLeft, &ptr);
return (size_t)(size - sizeLeft);
return 0;
}
static int
macFileFlush(
PgpFile * file)
{
MacFile * mf = (MacFile *)file->priv;
IOParam pb;
pb.ioRefNum = mf->dataRef;
PBFlushFileSync((ParmBlkPtr)&pb);
pb.ioRefNum = mf->resRef;
PBFlushFileSync((ParmBlkPtr)&pb);
return PGPERR_OK;
}
static int
macFileClose(
PgpFile * file)
{
MacFile * mf = (MacFile *)file->priv;
PrepareToWrite(file);
if (mf->dataRef != 0)
FSClose(mf->dataRef);
if (mf->resRef != 0)
FSClose(mf->resRef);
SetFileInfo(file);
pgpFreeFileRef(mf->fileRef);
pgpClearMemory((void *)mf, sizeof(*mf));
pgpFree(mf);
pgpFree(file);
return PGPERR_OK;
}
static long
macFileTell(
PgpFile * file)
{
MacFile * mf = (MacFile *)file->priv;
return mf->filePos;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -