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

📄 pgpmacfile.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 3 页
字号:
    return PGPERR_OK;
macError:
   result = pgpErrorFromMacError(macResult, PGPERR_FILE_OPFAIL);
error:
   macSetError(file, result);
   return result;
}

/*
 * This routine is called after closing a MacBinary file for writing. It
 * sets the finder information including type and creator.
 */
    static PGPError
SetFileInfo(
    PgpFile *     file)
{
    MacFile *     mf = (MacFile *)file->priv;
    FSSpec        spec;
    HFileParam    pb;

    if (!(mf->flags & kPGPMacWrite) || !(mf->flags & kPGPMacBinMode))
        return PGPERR_OK;

    if (pgpFSSpecFromFileRef(mf->fileRef, &spec) != PGPERR_OK)
        goto error;

    pb.ioNamePtr = spec.name;
    pb.ioVRefNum = spec.vRefNum;
    pb.ioDirID = spec.parID;
    pb.ioFlCrDat = mf->macBinHeader.creation;
    pb.ioFlMdDat = mf->macBinHeader.modification;
    pgpCopyMemory(&mf->macBinHeader.info1, &pb.ioFlFndrInfo,
                  sizeof(pb.ioFlFndrInfo));
    pb.ioFlFndrInfo.fdFlags &= 0xFF00;
    pb.ioFlFndrInfo.fdFlags |= mf->macBinHeader.info2;
    pb.ioFlFndrInfo.fdFlags &= ~NOMODIFY;
    pb.ioFlFndrInfo.fdLocation.h = 0;
    pb.ioFlFndrInfo.fdLocation.v = 0;
    pb.ioFlFndrInfo.fdFldr = 0;
    if (PBHSetFInfoSync((HParmBlkPtr)&pb) != noErr)
        goto error;

    return PGPERR_OK;

error:
    /* XXX Improve error reporting */
    macSetError(file, PGPERR_FILE_OPFAIL);
    return PGPERR_FILE_OPFAIL;
}

/*
 * It should be noted that writing to MacBinary files won't work if seeking
 * is used in certain ways. The MacBinary header only interpreted the first
 * time data is written past the first 128 bytes, and then the fork lengths
 * and offsets are fixed and immutable. This could be fixed at some point,
 * but there's no need for it now.
 *
 * The filename used to create the file is always the <fileRef> passed in,
 * not the name in the MacBinary header.
 */
    PgpFile *
pgpFileRefMacWriteOpen(
    PGPFileRef const *  fileRef,
    PGPFileType         fileType,
    PGPFileOpenFlags    flags,
    PGPError *          errorCode)
{
    PgpFile *   file = NULL;
    MacFile *   mf = NULL;
    FSSpec      spec;
    PGPError    result = PGPERR_OK;

    if ((file = (PgpFile *)pgpAlloc(sizeof(*file))) == NULL)
    {
        result = PGPERR_NOMEM;
        goto error;
    }

    if ((mf = (MacFile *)pgpAlloc(sizeof(*mf))) == NULL)
    {
        result = PGPERR_NOMEM;
        goto error;
    }

    pgpClearMemory(mf, sizeof(*mf));
    pgpClearMemory(file, sizeof(*file));

    mf->fileRef = pgpCopyFileRef(fileRef);
    if ((result = pgpFSSpecFromFileRef(mf->fileRef, &spec)) != PGPERR_OK)
        goto error;
    mf->fileType = fileType;

    /* Try to delete the file first, in case it already exists */
    /* XXX Maybe we should check the error, and/or truncate the file instead */
    HDelete(spec.vRefNum, spec.parID, spec.name);

    pgpAssert(sizeof(mf->macBinHeader) >= 129);
    pgpAssert((flags & kPGPFileOpenLocalEncodeHashOnly) == 0);

    mf->flags = kPGPMacWrite;

    if (flags & (kPGPFileOpenMaybeLocalEncode | kPGPFileOpenForceLocalEncode))
    {
        mf->flags |= kPGPCheckMacBin;
        if (flags & kPGPFileOpenNoMacBinCRCOkay)
            mf->flags |= kPGPNoMacBinCRCOkay;
        mf->dataOffset = mf->resOffset = 128;
    }
    else
        mf->dataOffset = mf->resOffset = 0;

    mf->dataRef = mf->resRef = 0;
    mf->totalSize = 0;
    mf->filePos = 0;

    file->priv = mf;
    file->read = macFileRead;
    file->write = macFileWrite;
    file->flush = macFileFlush;
    file->close = macFileClose;
    file->tell = macFileTell;
    file->seek = macFileSeek;
    file->eof = macFileEof;
    file->sizeAdvise = macFileSizeAdvise;
    file->error = macFileError;
    file->clearError = macFileClearError;
    file->write2read = macFileWrite2Read;
    file->cfb = macFileCfb;

    if (!(mf->flags & kPGPCheckMacBin))
        if ((result = PrepareToWrite(file)) != PGPERR_OK)
            goto error;

    return file;
error:
    if (mf != NULL)
    {
        if (mf->fileRef != NULL)
            pgpFreeFileRef(mf->fileRef);
        pgpFree(mf);
    }
    if (file != NULL)
        pgpFree(file);
    if (errorCode != NULL)
    {
        pgpAssertAddrValid(errorCode, PGPError);
        *errorCode = result;
    }
    return NULL;
}

    PgpFile *
pgpFileRefMacReadOpen(
    PGPFileRef const *  fileRef,
    PGPFileOpenFlags    flags,
    PGPError *          errorCode)
{
    PgpFile *           file = NULL;
    MacFile *           mf = NULL;
    FSSpec              spec;
    HFileParam          pb;
    HParamBlockRec      io;
    ushort              crc;
    PGPError            result = PGPERR_OK;

    if ((file = (PgpFile *)pgpAlloc(sizeof(*file))) == NULL)
    {
        result = PGPERR_NOMEM;
        goto error;
    }

    if ((mf = (MacFile *)pgpAlloc(sizeof(*mf))) == NULL)
    {
        result = PGPERR_NOMEM;
        goto error;
    }

    pgpClearMemory(mf, sizeof(*mf));
    pgpClearMemory(file, sizeof(*file));

    mf->fileRef = pgpCopyFileRef(fileRef);
    if ((result = pgpFSSpecFromFileRef(mf->fileRef, &spec)) != PGPERR_OK)
        goto error;
    mf->fileType = kPGPFileTypeNone;

    pb.ioNamePtr = spec.name;
    pb.ioVRefNum = spec.vRefNum;
    pb.ioDirID = spec.parID;
    pb.ioFDirIndex = 0;
    if (PBHGetFInfoSync((HParmBlkPtr)&pb) != noErr)
    {
        result = pgpErrorFromMacError(pb.ioResult, PGPERR_NO_FILE);
        goto error;
    }

    pgpAssert(sizeof(mf->macBinHeader) >= 129);
    pgpClearMemory(&mf->macBinHeader, sizeof(mf->macBinHeader));
    CopyPString(spec.name, mf->macBinHeader.name);
    mf->macBinHeader.info2 = pb.ioFlFndrInfo.fdFlags & 0x00FF;
    pb.ioFlFndrInfo.fdFlags &= 0xFF00;
    pb.ioFlFndrInfo.fdLocation.h = 0;
    pb.ioFlFndrInfo.fdLocation.v = 0;
    pb.ioFlFndrInfo.fdFldr = 0;
    mf->macBinHeader.info1 = pb.ioFlFndrInfo;
    mf->macBinHeader.dLength = pb.ioFlLgLen;
    mf->macBinHeader.rLength = pb.ioFlRLgLen;
    mf->macBinHeader.creation = pb.ioFlCrDat;
    mf->macBinHeader.modification = pb.ioFlMdDat;
    mf->macBinHeader.newVersion = 129;
    mf->macBinHeader.minimumVersion = 129;
    crc = CalcCRC16((uchar *)&mf->macBinHeader + 1, 124);
    pgpAssert(sizeof(crc) == 2);
    pgpCopyMemory(&crc, &mf->macBinHeader.crc1, sizeof(crc));

    mf->flags = kPGPMacRead;
    if (flags & kPGPFileOpenMaybeLocalEncode)
    {
        int   i;
        mf->flags |= kPGPMacBinMode;
        for (i = 0; nonMacBinaryTypes[i] != 0; i++)
            if (pb.ioFlFndrInfo.fdType == nonMacBinaryTypes[i])
            {
                mf->flags &= ~kPGPMacBinMode;
                break;
            }
    }
    else if (flags & kPGPFileOpenForceLocalEncode)
        mf->flags |= kPGPMacBinMode;

    io.fileParam.ioNamePtr = spec.name;
    io.fileParam.ioVRefNum = spec.vRefNum;
    io.fileParam.ioDirID = spec.parID;
    io.ioParam.ioPermssn = fsRdPerm;
    if (PBHOpenDFSync(&io) != noErr)
    {
        result = pgpErrorFromMacError(io.ioParam.ioResult, PGPERR_NO_FILE);
        goto error;
    }
    mf->dataRef = io.ioParam.ioRefNum;

    if (mf->flags & kPGPMacBinMode)
    {
        io.fileParam.ioNamePtr = spec.name;
        io.fileParam.ioVRefNum = spec.vRefNum;
        io.fileParam.ioDirID = spec.parID;
        io.ioParam.ioPermssn = fsRdPerm;
        if (PBHOpenRFSync(&io) != noErr)
        {
            result = pgpErrorFromMacError(io.ioParam.ioResult, PGPERR_NO_FILE);
            goto error;
        }
        mf->resRef = io.ioParam.ioRefNum;

        mf->dataOffset = 128;
        mf->resOffset = mf->dataOffset + (pb.ioFlLgLen + 127) & ~127L;
        mf->totalSize = mf->resOffset + (pb.ioFlRLgLen + 127) & ~127L;
        if (flags & kPGPFileOpenLocalEncodeHashOnly)
        {
            mf->flags |= kPGPMacBinHashOnly;
            /* Clear the finder flags */
            mf->macBinHeader.info1.fdFlags = 0;
            mf->macBinHeader.info2 = 0;
            /* Clear the creation and modification dates */
            mf->macBinHeader.creation = 0;
            mf->macBinHeader.modification = 0;
            /* Clear the filename */
            pgpClearMemory(mf->macBinHeader.name,
                           sizeof(mf->macBinHeader.name));
            /*
             * Clear the CRC so that if this output gets used to
             * recreate a file (which it shouldn't), it won't work
             * properly and someone will notice the problem.
             */
            pgpClearMemory(&mf->macBinHeader.crc1, sizeof(crc));
        }
    }
    else
    {
        mf->resRef = 0;
        mf->dataOffset = 0;
        mf->totalSize = mf->resOffset = pb.ioFlLgLen;
    }

    mf->filePos = 0;

    file->priv = mf;
    file->read = macFileRead;
    file->write = macFileWrite;
    file->flush = macFileFlush;
    file->close = macFileClose;
    file->tell = macFileTell;
    file->seek = macFileSeek;
    file->eof = macFileEof;
    file->sizeAdvise = macFileSizeAdvise;
    file->error = macFileError;
    file->clearError = macFileClearError;
    file->write2read = macFileWrite2Read;
    file->cfb = macFileCfb;
    return file;
error:
    if (mf != NULL)
    {
        if (mf->fileRef != NULL)
            pgpFreeFileRef(mf->fileRef);
        pgpFree(mf);
    }
    if (file != NULL)
        pgpFree(file);
    if (errorCode != NULL)
    {
        pgpAssertAddrValid(errorCode, PGPError);
        *errorCode = result;
    }
    return NULL;
}

    PGPError
pgpMacCalcFileSize(
    PGPFileRef const *  fileRef,
    PGPFileOpenFlags    flags,
    size_t *            fileSize)
{
    FSSpec      spec;
    HFileParam  pb;
    Boolean     macBinMode;
    PGPError    result = PGPERR_OK;

    *fileSize = 0;  /* In case there's an error */

    if ((result = pgpFSSpecFromFileRef(fileRef, &spec)) != PGPERR_OK)
        return result;

    pb.ioNamePtr = spec.name;
    pb.ioVRefNum = spec.vRefNum;
    pb.ioDirID = spec.parID;
    pb.ioFDirIndex = 0;
    if (PBHGetFInfoSync((HParmBlkPtr)&pb) != noErr)
        return pgpErrorFromMacError(pb.ioResult, PGPERR_NO_FILE);

    macBinMode = FALSE;
    if (flags & kPGPFileOpenMaybeLocalEncode)
    {
        int   i;

        macBinMode = TRUE;
        for (i = 0; nonMacBinaryTypes[i] != 0; i++)
            if (pb.ioFlFndrInfo.fdType == nonMacBinaryTypes[i])
            {
                macBinMode = FALSE;
                break;
            }
    }
    else if (flags & kPGPFileOpenForceLocalEncode)
        macBinMode = TRUE;

    if (macBinMode)
    {
        *fileSize = 128 +                /* MacBinary header */
            ((pb.ioFlLgLen + 127) & ~127L) +  /* Data fork */
            ((pb.ioFlRLgLen + 127) & ~127L);  /* Resource fork */
    }
    else
        *fileSize = pb.ioFlLgLen;

    return PGPERR_OK;
}

/*
 * Local Variables:
 * tab-width: 4
 * End:
 * vi: ts=4 sw=4
 * vim: si
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -