📄 pgpfileref.c
字号:
/*
* pgpFileRef.c -- Platform independent filename handling module
*
* Copyright (C) 1997 Pretty Good Privacy, Inc. All rights reserved.
*
* $Id: pgpFileRef.c,v 1.35.2.4 1997/06/07 09:50:05 mhw Exp $
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_PATHS_H
#include <paths.h>
#endif
#if UNIX || WIN32
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#endif
#include <errno.h>
#include <stdio.h>
#include <string.h>
#if MACINTOSH
#include <unix.h>
#endif
#include "pgpFileRef.h"
#include "pgpFileNames.h"
#include "pgpErr.h"
#include "pgpTypes.h"
#include "pgpDebug.h"
#include "pgpMem.h"
#if MACINTOSH
#include "MacFiles.h"
#include "MacStrings.h"
#include "pgpMacFile.h"
#include "pgpMacUtils.h"
#endif
#if !defined(_PATH_TMP) && UNIX && HAVE_MKSTEMP
#define _PATH_TMP "/tmp/"
#endif
#define kPGPFileRefMagic 0x251DEA9B
#define kPGPExternalFileRefMagic 0xD8AB1093
typedef enum PGPFileRefType_
{
kPGPFileRefFullPath = 1,
kPGPFileRefMacV1
} PGPFileRefType;
struct PGPFileRef_
{
ulong magic;
size_t size;
PGPFileRefType type;
};
#define pgpFileRefData(fileRef, type) ((type *)((fileRef) + 1))
#define pgpaPGPFileRefValid(fileRef) \
pgpaAddrValid(fileRef, PGPFileRef), \
pgpaAssert(fileRef->magic == kPGPFileRefMagic)
#define pgpaPGPFileTypeValid(fileType) \
pgpaAssert(fileType > kPGPFileTypeNone \
&& fileType < kPGPFileTypeNumTypes)
/* These must be kept in sync with the PGPFileType decl in pgpFileRef.h */
#if MACINTOSH /* [ */
static struct MacFileTypeEntry
{
OSType creator, type;
} sMacFileTypeTable[kPGPFileTypeNumTypes] = {
{ 0L, 0L }, /* kPGPFileTypeNone */
{ 'pgpK', 'pref' }, /* kPGPFileTypePrefs */
{ 'pgpK', 'pgPR' }, /* kPGPFileTypePubRing */
{ 'pgpK', 'pgRR' }, /* kPGPFileTypePrivRing */
{ 'pgpM', kPGPMacFileTypeDetachedSig }, /* kPGPFileTypeDetachedSig */
{ 'pgpK', 'pgRS' }, /* kPGPFileTypeRandomSeed */
{ 'pgpK', 'TEXT' }, /* kPGPFileTypeExportedKeys */
{ 'pgpM', kPGPMacFileTypeArmorFile }, /* kPGPFileTypeArmorFile */
{ 'pgpM', kPGPMacFileTypeEncryptedData }, /* kPGPFileTypeEncryptedData */
/* XXX: The below should be user preferences */
{ 'ttxt', 'TEXT' }, /* kPGPFileTypeDecryptedText */
{ '????', 'BINA' }, /* kPGPFileTypeDecryptedBin */
{ 'pgpM', kPGPMacFileTypeSignedData } /* kPGPFileTypeSignedData */
};
#endif /* ] MACINTOSH */
#if UNIX /* [ */
static struct UnixFileTypeEntry
{
mode_t mask; /* umask value for permissions */
} sUnixFileTypeTable[kPGPFileTypeNumTypes] = {
{ 0 }, /* kPGPFileTypeNone */
{ 0077 }, /* kPGPFileTypePrefs */
{ 0077 }, /* kPGPFileTypePubRing */
{ 0077 }, /* kPGPFileTypePrivRing */
{ 0077 }, /* kPGPFileTypeDetachedSig */
{ 0077 }, /* kPGPFileTypeRandomSeed */
{ 0077 }, /* kPGPFileTypeExportedKeys */
{ 0077 }, /* kPGPFileTypeArmorFile */
{ 0077 }, /* kPGPFileTypeEncryptedData */
{ 0077 }, /* kPGPFileTypeDecryptedText */
{ 0077 }, /* kPGPFileTypeDecryptedBin */
{ 0077 } /* kPGPFileTypeSignedData */
};
#endif /* ] UNIX */
PGPFileRef *
pgpNewFileRefFromFullPath(
char const * path)
{
PGPFileRef * fileRef;
size_t size = sizeof(PGPFileRef) + strlen(path) + 1;
fileRef = (PGPFileRef *)pgpAlloc(size);
if (fileRef)
{
fileRef->magic = kPGPFileRefMagic;
fileRef->size = size;
fileRef->type = kPGPFileRefFullPath;
strcpy(pgpFileRefData(fileRef, char), path);
}
return fileRef;
}
PGPError
pgpFullPathFromFileRef(
PGPFileRef const * fileRef,
char ** fullPathPtr)
{
pgpa(pgpaPGPFileRefValid(fileRef));
*fullPathPtr = NULL;
switch (fileRef->type)
{
case kPGPFileRefFullPath:
{
char const * path;
size_t size;
path = pgpFileRefData(fileRef, char);
size = strlen(path) + 1;
*fullPathPtr = (char *)pgpAlloc(size);
pgpCopyMemory(path, *fullPathPtr, size);
break;
}
#if MACINTOSH /* [ */
case kPGPFileRefMacV1:
{
uchar path[256];
if (FSpGetFullPath(pgpFileRefData(fileRef, FSSpec), path) != noErr)
return PGPERR_NO_FILE;
*fullPathPtr = (char *)pgpAlloc(path[0] + 1);
pgpCopyMemory(path + 1, *fullPathPtr, path[0]);
(*fullPathPtr)[path[0]] = '\0';
break;
}
#endif /* ] MACINTOSH */
default:
pgpAssertMsg(0, "Unsupported PGPFileRef type");
return PGPERR_NO_FILE;
}
return PGPERR_OK;
}
#if MACINTOSH /* [ */
PGPFileRef *
pgpNewFileRefFromFSSpec(
FSSpec const * spec)
{
PGPFileRef * fileRef;
size_t size = sizeof(PGPFileRef) + sizeof(FSSpec);
fileRef = (PGPFileRef *)pgpAlloc(size);
if (fileRef)
{
fileRef->magic = kPGPFileRefMagic;
fileRef->size = size;
fileRef->type = kPGPFileRefMacV1;
pgpCopyMemory(spec, pgpFileRefData(fileRef, FSSpec), sizeof(FSSpec));
}
return fileRef;
}
PGPError
pgpFSSpecFromFileRef(
PGPFileRef const * fileRef,
FSSpec * spec)
{
pgpa(pgpaPGPFileRefValid(fileRef));
switch (fileRef->type)
{
#ifdef NOTYET
case kPGPFileRefFullPath:
break;
#endif
case kPGPFileRefMacV1:
pgpCopyMemory(pgpFileRefData(fileRef, FSSpec), spec,
sizeof(*spec));
break;
default:
pgpAssertMsg(0, "Unsupported PGPFileRef type");
return PGPERR_NO_FILE;
}
return PGPERR_OK;
}
#endif /* ] MACINTOSH */
PGPFileRef *
pgpCopyFileRef(
PGPFileRef const * fileRef)
{
PGPFileRef * newFileRef;
pgpa(pgpaPGPFileRefValid(fileRef));
/*
* XXX In the future if PGPFileRefs contain pointers,
* this will need to be changed.
*/
newFileRef = (PGPFileRef *)pgpAlloc(fileRef->size);
if (newFileRef != NULL)
pgpCopyMemory(fileRef, newFileRef, fileRef->size);
return newFileRef;
}
void
pgpFreeFileRef(
PGPFileRef * fileRef)
{
pgpa(pgpaPGPFileRefValid(fileRef));
pgpClearMemory((void *)fileRef, fileRef->size);
pgpFree(fileRef);
}
/*
* pgpGetFileRefName returns a string allocated with pgpAlloc(),
* which the caller is responsible for freeing.
*/
char *
pgpGetFileRefName(
PGPFileRef const * fileRef)
{
char const * name;
size_t nameLen;
char * allocName;
pgpa(pgpaPGPFileRefValid(fileRef));
switch (fileRef->type)
{
case kPGPFileRefFullPath:
{
char const * path;
path = pgpFileRefData(fileRef, char);
name = (char const *)pgpFileNameTail(path);
nameLen = strlen(name);
break;
}
#if MACINTOSH /* [ */
case kPGPFileRefMacV1:
{
FSSpec const * spec;
spec = pgpFileRefData(fileRef, FSSpec);
name = (char const *)spec->name + 1;
nameLen = spec->name[0];
break;
}
#endif /* ] MACINTOSH */
default:
pgpAssertMsg(0, "Unsupported PGPFileRef type");
return NULL;
}
allocName = (char *)pgpAlloc(nameLen + 1);
if (allocName != NULL)
{
pgpCopyMemory(name, allocName, nameLen);
allocName[nameLen] = '\0';
}
return allocName;
}
PGPError
pgpSetFileRefName(
PGPFileRef ** fileRef1,
char const * newName)
{
PGPFileRef * fileRef = *fileRef1;
PGPError result = PGPERR_OK;
size_t nameLen;
pgpa((
pgpaPGPFileRefValid(fileRef),
pgpaStrValid(newName)));
nameLen = strlen(newName);
switch (fileRef->type)
{
case kPGPFileRefFullPath:
{
char * path;
size_t nameOffset;
size_t newSize;
path = pgpFileRefData(fileRef, char);
nameOffset = pgpFileNameTail(path) - path;
newSize = sizeof(PGPFileRef) + nameOffset + nameLen + 1;
result = pgpRealloc((void **)fileRef1, newSize);
fileRef = *fileRef1;
if (result == PGPERR_OK)
{
path = pgpFileRefData(fileRef, char);
strcpy(path + nameOffset, newName);
fileRef->size = newSize;
}
break;
}
#if MACINTOSH /* [ */
case kPGPFileRefMacV1:
{
FSSpec * spec;
if (nameLen >= 64)
return PGPERR_KEYDB_VALUETOOLONG;
spec = pgpFileRefData(fileRef, FSSpec);
spec->name[0] = nameLen;
pgpCopyMemory(newName, (char *)spec->name + 1, nameLen);
break;
}
#endif /* ] MACINTOSH */
default:
pgpAssertMsg(0, "Unsupported PGPFileRef type");
return PGPERR_BADPARAM;
}
return result;
}
uchar *
pgpExportFileRef(
PGPFileRef const * fileRef,
size_t * size)
{
PGPFileRef * externFileRef = NULL;
size_t externSize;
pgpa((
pgpaPGPFileRefValid(fileRef),
pgpaAddrValid(size, size_t)));
*size = 0;
/*
* XXX In the future if PGPFileRefs contain pointers,
* this will need to be changed.
*/
switch (fileRef->type)
{
case kPGPFileRefFullPath:
externSize = fileRef->size;
externFileRef = (PGPFileRef *)pgpAlloc(externSize);
if (externFileRef != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -