⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpmacfile.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -