📄 pgpfilespecstd.c
字号:
/*____________________________________________________________________________
Copyright (C) 1997 Network Associates Inc. and affiliated companies.
All rights reserved.
$Id: pgpFileSpecStd.c,v 1.50 1999/03/25 18:13:34 melkins Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"
#include <stdio.h>
#if PGP_COMPILER_SUN
int fileno(FILE *stream);
#endif
#include <string.h>
#include <errno.h>
#if HAVE_PATHS_H
#include <paths.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_DIRENT_H && !PGP_WIN32
#include <dirent.h>
#define USE_DIRENT 1
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "pgpDebug.h"
#include "pgpPFLErrors.h"
#include "pgpMem.h"
#include "pgpMemoryMgr.h"
#define PGP_USE_FILE_SPEC_PRIV 1
#include "pgpFileSpecStdPriv.h"
typedef struct MyData
{
char path[ 1 ];
} MyData;
#define GetMyData( ref ) ( (MyData *)((ref)->data) )
#define SetMyData( ref, newData ) ( ((ref)->data) = (MyData *)newData )
#define MyDataSize( ref ) ( strlen( GetMyData(ref)->path ) + 1)
#if USE_DIRENT
struct PFLDirectoryIter
{
PGPMemoryMgrRef memoryMgr;
DIR * dirRef;
PFLFileSpecRef parentDir;
};
#endif
static PGPError sExportProc( PFLConstFileSpecRef ref,
PGPByte **data, PGPSize *dataSize );
static PGPError sImportProc( PFLFileSpecRef ref,
PGPByte const *data, PGPSize dataSize );
static PGPError sGetNameProc( PFLConstFileSpecRef ref, char name[ 256 ] );
static PGPError sSetNameProc( PFLFileSpecRef ref, char const *name );
static PGPError sSetMetaInfoProc( PFLFileSpecRef ref, void const *info );
static PGPError sExistsProc( PFLFileSpecRef ref, PGPBoolean *exists);
static PGPError sCreateProc( PFLFileSpecRef ref );
static PGPError sDeleteProc( PFLConstFileSpecRef ref );
static PGPError sRenameProc( PFLFileSpecRef ref, const char *newName);
static PGPError sGetMaxNameLengthProc( PFLConstFileSpecRef ref,
PGPSize * maxNameLength);
static PGPError sParentDirProc( PFLConstFileSpecRef fileFromDir,
PFLFileSpecRef *outParent);
static PGPError sComposeProc( PFLConstFileSpecRef parent, char const *name,
PFLFileSpecRef *outRef );
static const PGPFileSpecVTBL sVTBLStd =
{
sExportProc,
sImportProc,
sGetNameProc,
sSetNameProc,
sSetMetaInfoProc,
sExistsProc,
sCreateProc,
sDeleteProc,
sRenameProc,
sGetMaxNameLengthProc,
sParentDirProc,
sComposeProc
};
PGPFileSpecVTBL const *
GetFileSpecVTBLStd()
{
return( &sVTBLStd );
}
/*
* kDirectorySeparators is a string of possible directory-separation characters
* The first one is the preferred one, which goes in between
* PGPPATH and the file name if PGPPATH is not terminated with a
* directory separator.
*
* PATHSEP is a the directory separator within a PATH of directories.
* Only one character per platform, please
*/
#if defined(PGP_MSDOS) || defined(PGP_ATARI) || defined(PGP_WIN32)
static char const kDirectorySeparators[] = "\\/";
#define PATHSEP ';'
#define SINGLE_EXT 1
#elif defined(PGP_UNIX)
static char const kDirectorySeparators[] = "/";
#define PATHSEP ':'
#elif defined(PGP_AMIGA)
static char const kDirectorySeparators[] = "/:";
#define PATHSEP ';'
#elif defined(PGP_VMS)
static char const kDirectorySeparators[] = "]:"; /* Any more? */
#define PATHSEP ';'
#define SINGLE_EXT 1
#elif defined(PGP_MACINTOSH)
static char const kDirectorySeparators[] = ":";
#define PATHSEP ';'
#else
#error Unknown operating system - need one of\
UNIX, MSDOS, AMIGA, ATARI, VMS, or MACINTOSH.
#endif
static char const *
pgpFileNameTail( char const *path )
{
char const * lastTail = path;
char const * separator;
for (separator = kDirectorySeparators; *separator != '\0'; ++separator)
{
char const * tail;
tail = strrchr(lastTail, *separator);
if ( IsntNull( tail ) )
lastTail = tail + 1;
}
return( lastTail );
}
#if ! PGP_MACINTOSH /* [ */
PGPError
pgpPlatformOpenFileSpecAsFILE(
PFLFileSpecRef spec,
const char * openMode,
FILE ** fileOut )
{
PGPError err = kPGPError_NoErr;
FILE * stdioFILE = NULL;
char * fullPath;
PGPValidatePtr( fileOut );
*fileOut = NULL;
PFLValidateFileSpec( spec );
PGPValidatePtr( openMode );
PGPValidateParam( spec->type == kPFLFileSpecFullPathType );
err = PFLGetFullPathFromFileSpec( spec, &fullPath );
if ( IsntPGPError( err ) )
{
stdioFILE = fopen( fullPath, openMode );
PGPFreeData( fullPath );
if ( IsNull( stdioFILE ) )
{
if (errno == EACCES
#ifdef EROFS
|| errno == EROFS
#endif
)
{
err = kPGPError_FilePermissions;
}
else if (errno == ENOENT)
{
err = kPGPError_FileNotFound;
}
else
{
err = kPGPError_FileOpFailed;
}
}
}
*fileOut = stdioFILE;
return( err );
}
PGPError
PFLNewFileSpecFromFullPath(
PGPMemoryMgrRef memoryMgr,
char const * path,
PFLFileSpecRef * outRef )
{
PFLFileSpecRef newFileRef = NULL;
PGPError err = kPGPError_NoErr;
PGPValidatePtr( outRef );
*outRef = NULL;
PGPValidateMemoryMgr( memoryMgr );
err = pgpNewFileSpec( memoryMgr, kPFLFileSpecFullPathType,
strlen(path) + 1, &newFileRef );
if ( IsntPGPError( err ) )
{
MyData * myData = GetMyData( newFileRef );
strcpy( myData->path, path );
}
*outRef = newFileRef;
return err;
}
PGPError
PFLGetFullPathFromFileSpec(
PFLConstFileSpecRef fileRef,
char ** fullPathPtr)
{
PGPError err = kPGPError_NoErr;
char const * srcPath;
char * newPath = NULL;
MyData * myData = GetMyData( fileRef );
PGPValidatePtr( fullPathPtr );
*fullPathPtr = NULL;
PFLValidateFileSpec( fileRef );
PGPValidateParam( fileRef->type == kPFLFileSpecFullPathType );
srcPath = myData->path;
newPath = (char *)PGPNewData( fileRef->memoryMgr,
strlen( myData->path ) + 1, 0);
if ( IsntNull( newPath ) )
strcpy( newPath, myData->path );
else
err = kPGPError_OutOfMemory;
*fullPathPtr = newPath;
return err;
}
PGPError
pgpPlatformGetTempFileSpec(
PGPMemoryMgrRef memoryMgr,
PFLConstFileSpecRef optionalRef,
PFLFileSpecRef * outRef )
{
char fileName[ L_tmpnam ];
PGPError err = kPGPError_NoErr;
PFLFileSpecRef tempRef = NULL;
(void)optionalRef;
#if defined(_PATH_TMP) && HAVE_MKTEMP /* [ */
{
strncpy(fileName, _PATH_TMP "ptmpXXXXXX", sizeof(fileName));
fileName[ sizeof(fileName) - 1 ] = '\0';
if ( IsNull( mktemp(fileName) ) )
{
err = kPGPError_FileOpFailed;
}
if ( IsntPGPError( err ) )
{
err = PFLNewFileSpecFromFullPath( memoryMgr, fileName, &tempRef);
}
}
#else /* ] defined(_PATH_TMP) && HAVE_MKTEMP [ */
if ( tmpnam(fileName) != fileName)
{
err = kPGPError_FileOpFailed;
}
err = PFLNewFileSpecFromFullPath( memoryMgr, fileName, &tempRef);
#endif /* ] defined(_PATH_TMP) && HAVE_MKTEMP */
*outRef = tempRef;
return err;
}
#define PGP_ISDIR(m) ( ( ( m ) & S_IFDIR ) != 0 )
#define PGP_ISREG(m) ( ( ( m ) & S_IFREG ) != 0 )
PGPError
pgpPlatformGetFileInfo(
PFLConstFileSpecRef spec,
PFLFileInfo * outInfo )
{
PGPError err = kPGPError_NoErr;
const char * path = GetMyData( spec )->path;
struct stat statInfo;
PGPValidateParam( spec->type == kPFLFileSpecFullPathType );
if ( stat( path, &statInfo ) != 0 )
{
err = kPGPError_FileOpFailed;
}
else
{
outInfo->flags = 0;
if ( PGP_ISDIR( statInfo.st_mode ) )
outInfo->flags |= kPGPFileInfo_IsDirectory;
if ( PGP_ISREG( statInfo.st_mode ) )
{
outInfo->flags |= kPGPFileInfo_IsPlainFile;
outInfo->dataLength = statInfo.st_size;
}
else
{
outInfo->dataLength = 0;
}
outInfo->modificationTime = statInfo.st_mtime;
}
return err;
}
PGPError
pgpPlatformLockFILE(
FILE * file,
PFLFileOpenFlags flags )
{
PGPError err = kPGPError_NoErr;
#if HAVE_FCNTL_H && defined(F_SETLK)
int fileDesc = fileno( file );
struct flock lockInfo;
if ( flags & kPFLFileOpenFlags_ReadWrite )
lockInfo.l_type = F_WRLCK;
else
lockInfo.l_type = F_RDLCK;
lockInfo.l_start = 0;
lockInfo.l_whence = SEEK_SET;
lockInfo.l_len = 0;
if ( fcntl( fileDesc, F_SETLK, &lockInfo ) == -1 )
{
if ( errno == EACCES || errno == EAGAIN )
err = kPGPError_FileLocked;
else if ( errno == ENOENT )
err = kPGPError_FileNotFound;
else
err = kPGPError_FileOpFailed;
}
#elif PGP_MACINTOSH || PGP_WIN32
/* Locking on MacOS and Win32 is done during open */
(void)file;
(void)flags;
#else
#error File locking needs to be implemented for this platform!
#endif
return err;
}
#endif /* ] PGP_MACINTOSH */
#if USE_DIRENT /* [ */
PGPError
pgpPlatformNewDirectoryIter(
PFLConstFileSpecRef parentDir,
PFLDirectoryIterRef * outIter )
{
PGPMemoryMgrRef memoryMgr = parentDir->memoryMgr;
const char * path = GetMyData( parentDir )->path;
PFLDirectoryIterRef newIter = NULL;
PGPError err = kPGPError_NoErr;
*outIter = NULL;
PGPValidateParam( parentDir->type == kPFLFileSpecFullPathType );
PGPValidateParam( PGPMemoryMgrIsValid( memoryMgr ) );
newIter = (PFLDirectoryIterRef)PGPNewData( memoryMgr,
sizeof( *newIter ), 0 );
if ( IsntNull( newIter ) )
{
newIter->memoryMgr = memoryMgr;
newIter->dirRef = opendir( path );
if ( IsNull( newIter->dirRef ) )
err = kPGPError_FileOpFailed; /* XXX Better error code? */
else
err = PFLCopyFileSpec( parentDir, &newIter->parentDir );
}
else
{
err = kPGPError_OutOfMemory;
}
if ( IsntPGPError( err ) )
*outIter = newIter;
else if ( IsntNull( newIter ) )
PGPFreeData( newIter );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -