Compare commits
23 Commits
main
...
release-3.
Author | SHA1 | Date |
---|---|---|
Ryan C. Gordon | f8f89035c4 | |
Ryan C. Gordon | 2dc2dd1b04 | |
Ryan C. Gordon | 81bb11ddbc | |
Ryan C. Gordon | fa34bb479d | |
Ryan C. Gordon | 9a825fcd77 | |
Ryan C. Gordon | 3ba1e363d1 | |
Ryan C. Gordon | 0d3d0afc9a | |
Ryan C. Gordon | 20da8fab65 | |
Ryan C. Gordon | 9ef9a06db3 | |
Ryan C. Gordon | 4a56820f1d | |
Ryan C. Gordon | b1c6c7f4a8 | |
Ryan C. Gordon | a828a91feb | |
Ryan C. Gordon | be0afe31e3 | |
Ryan C. Gordon | d08188c1e0 | |
Ryan C. Gordon | e216897cb9 | |
Ryan C. Gordon | ac1ee1a3f2 | |
Ryan C. Gordon | 9ea364e46e | |
Ryan C. Gordon | 179bd1d40a | |
Ryan C. Gordon | a80261989e | |
Ryan C. Gordon | b8aa7dab87 | |
Ryan C. Gordon | b9fd9e8100 | |
Ryan C. Gordon | e290b8d0a0 | |
Ryan C. Gordon | 12b7a80640 |
|
@ -12,7 +12,7 @@
|
|||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
project(PhysicsFS)
|
||||
set(PHYSFS_VERSION 3.0.0)
|
||||
set(PHYSFS_VERSION 3.0.2)
|
||||
|
||||
# Increment this if/when we break backwards compatibility.
|
||||
set(PHYSFS_SOVERSION 1)
|
||||
|
@ -232,8 +232,9 @@ if(DOXYGEN_FOUND)
|
|||
file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "OUTPUT_DIRECTORY = \"${CMAKE_CURRENT_BINARY_DIR}/docs\"\n")
|
||||
file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "\n# End auto-generated section.\n\n")
|
||||
|
||||
set(PHYSFS_TARGETNAME_DOCS "docs" CACHE STRING "Name of 'docs' build target")
|
||||
add_custom_target(
|
||||
docs
|
||||
${PHYSFS_TARGETNAME_DOCS}
|
||||
${DOXYGEN_EXECUTABLE} "${PHYSFS_OUTPUT_DOXYFILE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Building documentation in 'docs' directory..."
|
||||
|
@ -244,14 +245,18 @@ endif()
|
|||
|
||||
if(UNIX)
|
||||
set(PHYSFS_TARBALL "${CMAKE_CURRENT_SOURCE_DIR}/../physfs-${PHYSFS_VERSION}.tar.bz2")
|
||||
|
||||
set(PHYSFS_TARGETNAME_DIST "dist" CACHE STRING "Name of 'dist' build target")
|
||||
add_custom_target(
|
||||
dist
|
||||
${PHYSFS_TARGETNAME_DIST}
|
||||
hg archive -t tbz2 "${PHYSFS_TARBALL}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Building source tarball '${PHYSFS_TARBALL}'..."
|
||||
)
|
||||
|
||||
set(PHYSFS_TARGETNAME_UNINSTALL "uninstall" CACHE STRING "Name of 'uninstall' build target")
|
||||
add_custom_target(
|
||||
uninstall
|
||||
${PHYSFS_TARGETNAME_UNINSTALL}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/extras/uninstall.sh"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
COMMENT "Uninstall the project..."
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
Copyright (c) 2001-2017 Ryan C. Gordon and others.
|
||||
Copyright (c) 2001-2019 Ryan C. Gordon and others.
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from
|
||||
|
|
|
@ -164,6 +164,9 @@ CMake fixes:
|
|||
Bug fixes,
|
||||
Rémi Verschelde
|
||||
|
||||
Bug fixes:
|
||||
Rob Loach
|
||||
|
||||
Other stuff:
|
||||
Your name here! Patches go to icculus@icculus.org ...
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
The API documentation is readable in a few ways:
|
||||
|
||||
- Read physfs.h; it's _heavily_ documented and the primary source of reference
|
||||
documentation for the library.
|
||||
- Run Doxygen over the header, which produces nicer-to-browse documentation in
|
||||
HTML, LaTeX, manpage, etc formats. This is done for you if Doxygen is
|
||||
installed and you build the "docs" target in whatever project files CMake
|
||||
generated for you.
|
||||
- Too much trouble? We generated the HTML reference for you, online here:
|
||||
|
||||
https://icculus.org/physfs/docs/
|
||||
|
||||
- We would love well-written tutorials for the latest version of PhysicsFS!
|
||||
If you write one, we would love to list it here. Drop me a line about it:
|
||||
icculus@icculus.org ... Thanks!
|
||||
|
||||
--ryan.
|
||||
|
|
@ -50,18 +50,22 @@ static int locateOneElement(char *buf)
|
|||
ptr++; /* point past dirsep to entry itself. */
|
||||
} /* else */
|
||||
|
||||
for (i = rc; *i != NULL; i++)
|
||||
if (rc != NULL)
|
||||
{
|
||||
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
|
||||
for (i = rc; *i != NULL; i++)
|
||||
{
|
||||
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
||||
PHYSFS_freeList(rc);
|
||||
return 1;
|
||||
} /* if */
|
||||
} /* for */
|
||||
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
|
||||
{
|
||||
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
||||
PHYSFS_freeList(rc);
|
||||
return 1;
|
||||
} /* if */
|
||||
} /* for */
|
||||
|
||||
PHYSFS_freeList(rc);
|
||||
} /* if */
|
||||
|
||||
/* no match at all... */
|
||||
PHYSFS_freeList(rc);
|
||||
return 0;
|
||||
} /* locateOneElement */
|
||||
|
||||
|
|
|
@ -32,10 +32,16 @@
|
|||
#endif
|
||||
|
||||
#if !TARGET_SDL2
|
||||
#ifndef RW_SEEK_SET
|
||||
#define RW_SEEK_SET SEEK_SET
|
||||
#endif
|
||||
#ifndef RW_SEEK_CUR
|
||||
#define RW_SEEK_CUR SEEK_CUR
|
||||
#endif
|
||||
#ifndef RW_SEEK_END
|
||||
#define RW_SEEK_END SEEK_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TARGET_SDL2
|
||||
static Sint64 SDLCALL physfsrwops_size(struct SDL_RWops *rw)
|
||||
|
|
78
src/physfs.c
78
src/physfs.c
|
@ -879,13 +879,20 @@ static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
|
|||
|
||||
if (io == NULL)
|
||||
{
|
||||
/* file doesn't exist, etc? Just fail out. */
|
||||
PHYSFS_Stat statbuf;
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(d, &statbuf, 1), NULL);
|
||||
|
||||
/* DIR gets first shot (unlike the rest, it doesn't deal with files). */
|
||||
retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
|
||||
if (retval || claimed)
|
||||
return retval;
|
||||
if (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY)
|
||||
{
|
||||
retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
|
||||
if (retval || claimed)
|
||||
return retval;
|
||||
} /* if */
|
||||
|
||||
io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
|
||||
BAIL_IF_ERRPASS(!io, 0);
|
||||
BAIL_IF_ERRPASS(!io, NULL);
|
||||
created_io = 1;
|
||||
} /* if */
|
||||
|
||||
|
@ -939,6 +946,10 @@ static int sanitizePlatformIndependentPath(const char *src, char *dst)
|
|||
while (*src == '/') /* skip initial '/' chars... */
|
||||
src++;
|
||||
|
||||
/* Make sure the entire string isn't "." or ".." */
|
||||
if ((strcmp(src, ".") == 0) || (strcmp(src, "..") == 0))
|
||||
BAIL(PHYSFS_ERR_BAD_FILENAME, 0);
|
||||
|
||||
prev = dst;
|
||||
do
|
||||
{
|
||||
|
@ -1012,6 +1023,8 @@ static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
|
|||
DirHandle *dirHandle = NULL;
|
||||
char *tmpmntpnt = NULL;
|
||||
|
||||
assert(newDir != NULL); /* should have caught this higher up. */
|
||||
|
||||
if (mountPoint != NULL)
|
||||
{
|
||||
const size_t len = strlen(mountPoint) + 1;
|
||||
|
@ -1025,15 +1038,9 @@ static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
|
|||
dirHandle = openDirectory(io, newDir, forWriting);
|
||||
GOTO_IF_ERRPASS(!dirHandle, badDirHandle);
|
||||
|
||||
if (newDir == NULL)
|
||||
dirHandle->dirName = NULL;
|
||||
else
|
||||
{
|
||||
dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
|
||||
if (!dirHandle->dirName)
|
||||
GOTO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
|
||||
strcpy(dirHandle->dirName, newDir);
|
||||
} /* else */
|
||||
dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
|
||||
GOTO_IF(!dirHandle->dirName, PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
|
||||
strcpy(dirHandle->dirName, newDir);
|
||||
|
||||
if ((mountPoint != NULL) && (*mountPoint != '\0'))
|
||||
{
|
||||
|
@ -1599,7 +1606,7 @@ const char *PHYSFS_getPrefDir(const char *org, const char *app)
|
|||
assert(*endstr == dirsep);
|
||||
*endstr = '\0'; /* mask out the final dirsep for now. */
|
||||
|
||||
if (!__PHYSFS_platformStat(prefDir, &statbuf))
|
||||
if (!__PHYSFS_platformStat(prefDir, &statbuf, 1))
|
||||
{
|
||||
for (ptr = strchr(prefDir, dirsep); ptr; ptr = strchr(ptr+1, dirsep))
|
||||
{
|
||||
|
@ -1684,21 +1691,20 @@ static int doMount(PHYSFS_Io *io, const char *fname,
|
|||
DirHandle *prev = NULL;
|
||||
DirHandle *i;
|
||||
|
||||
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
|
||||
if (mountPoint == NULL)
|
||||
mountPoint = "/";
|
||||
|
||||
__PHYSFS_platformGrabMutex(stateLock);
|
||||
|
||||
if (fname != NULL)
|
||||
for (i = searchPath; i != NULL; i = i->next)
|
||||
{
|
||||
for (i = searchPath; i != NULL; i = i->next)
|
||||
{
|
||||
/* already in search path? */
|
||||
if ((i->dirName != NULL) && (strcmp(fname, i->dirName) == 0))
|
||||
BAIL_MUTEX_ERRPASS(stateLock, 1);
|
||||
prev = i;
|
||||
} /* for */
|
||||
} /* if */
|
||||
/* already in search path? */
|
||||
if ((i->dirName != NULL) && (strcmp(fname, i->dirName) == 0))
|
||||
BAIL_MUTEX_ERRPASS(stateLock, 1);
|
||||
prev = i;
|
||||
} /* for */
|
||||
|
||||
dh = createDirHandle(io, fname, mountPoint, 0);
|
||||
BAIL_IF_MUTEX_ERRPASS(!dh, stateLock, 0);
|
||||
|
@ -1725,6 +1731,7 @@ int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
const char *mountPoint, int appendToPath)
|
||||
{
|
||||
BAIL_IF(!io, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
BAIL_IF(io->version != 0, PHYSFS_ERR_UNSUPPORTED, 0);
|
||||
return doMount(io, fname, mountPoint, appendToPath);
|
||||
} /* PHYSFS_mountIo */
|
||||
|
@ -1738,6 +1745,7 @@ int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *),
|
|||
PHYSFS_Io *io = NULL;
|
||||
|
||||
BAIL_IF(!buf, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
|
||||
io = __PHYSFS_createMemoryIo(buf, len, del);
|
||||
BAIL_IF_ERRPASS(!io, 0);
|
||||
|
@ -1760,7 +1768,8 @@ int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
|
|||
int retval = 0;
|
||||
PHYSFS_Io *io = NULL;
|
||||
|
||||
BAIL_IF(file == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
BAIL_IF(!file, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
|
||||
|
||||
io = __PHYSFS_createHandleIo(file);
|
||||
BAIL_IF_ERRPASS(!io, 0);
|
||||
|
@ -1785,7 +1794,7 @@ int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
|
|||
|
||||
int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
|
||||
{
|
||||
return doMount(NULL, newDir, NULL, appendToPath);
|
||||
return PHYSFS_mount(newDir, NULL, appendToPath);
|
||||
} /* PHYSFS_addToSearchPath */
|
||||
|
||||
|
||||
|
@ -2660,7 +2669,6 @@ static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
|
|||
{
|
||||
FileHandle *prev = NULL;
|
||||
FileHandle *i;
|
||||
int rc = 1;
|
||||
|
||||
for (i = *list; i != NULL; i = i->next)
|
||||
{
|
||||
|
@ -2668,9 +2676,19 @@ static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
|
|||
{
|
||||
PHYSFS_Io *io = handle->io;
|
||||
PHYSFS_uint8 *tmp = handle->buffer;
|
||||
rc = PHYSFS_flush((PHYSFS_File *) handle);
|
||||
if (!rc)
|
||||
return -1;
|
||||
|
||||
/* send our buffer to io... */
|
||||
if (!handle->forReading)
|
||||
{
|
||||
if (!PHYSFS_flush((PHYSFS_File *) handle))
|
||||
return -1;
|
||||
|
||||
/* ...then have io send it to the disk... */
|
||||
else if (io->flush && !io->flush(io))
|
||||
return -1;
|
||||
} /* if */
|
||||
|
||||
/* ...then close the underlying file. */
|
||||
io->destroy(io);
|
||||
|
||||
if (tmp != NULL) /* free any associated buffer. */
|
||||
|
@ -2968,7 +2986,7 @@ int PHYSFS_flush(PHYSFS_File *handle)
|
|||
rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos);
|
||||
BAIL_IF_ERRPASS(rc <= 0, 0);
|
||||
fh->bufpos = fh->buffill = 0;
|
||||
return io->flush ? io->flush(io) : 1;
|
||||
return 1;
|
||||
} /* PHYSFS_flush */
|
||||
|
||||
|
||||
|
|
77
src/physfs.h
77
src/physfs.h
|
@ -225,11 +225,11 @@ extern "C" {
|
|||
|
||||
#if defined(PHYSFS_DECL)
|
||||
/* do nothing. */
|
||||
#elif (defined _MSC_VER)
|
||||
#elif defined(_MSC_VER)
|
||||
#define PHYSFS_DECL __declspec(dllexport)
|
||||
#elif (defined __SUNPRO_C)
|
||||
#elif defined(__SUNPRO_C)
|
||||
#define PHYSFS_DECL __global
|
||||
#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
|
||||
#elif ((__GNUC__ >= 3) && (!defined(__EMX__)) && (!defined(sun)))
|
||||
#define PHYSFS_DECL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define PHYSFS_DECL
|
||||
|
@ -434,7 +434,7 @@ typedef struct PHYSFS_Version
|
|||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
#define PHYSFS_VER_MAJOR 3
|
||||
#define PHYSFS_VER_MINOR 0
|
||||
#define PHYSFS_VER_PATCH 0
|
||||
#define PHYSFS_VER_PATCH 2
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
|
@ -2176,11 +2176,15 @@ PHYSFS_DECL int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator);
|
|||
* or each other, for example.
|
||||
*
|
||||
* The mountpoint does not need to exist prior to mounting, which is different
|
||||
* than those familiar with the Unix concept of "mounting" may not expect.
|
||||
* than those familiar with the Unix concept of "mounting" may expect.
|
||||
* As well, more than one archive can be mounted to the same mountpoint, or
|
||||
* mountpoints and archive contents can overlap...the interpolation mechanism
|
||||
* still functions as usual.
|
||||
*
|
||||
* Specifying a symbolic link to an archive or directory is allowed here,
|
||||
* regardless of the state of PHYSFS_permitSymbolicLinks(). That function
|
||||
* only deals with symlinks inside the mounted directory or archive.
|
||||
*
|
||||
* \param newDir directory or archive to add to the path, in
|
||||
* platform-dependent notation.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
|
@ -2760,6 +2764,12 @@ PHYSFS_DECL int PHYSFS_enumerate(const char *dir, PHYSFS_EnumerateCallback c,
|
|||
* This call will fail (and fail to remove from the path) if the element still
|
||||
* has files open in it.
|
||||
*
|
||||
* \warning This function wants the path to the archive or directory that was
|
||||
* mounted (the same string used for the "newDir" argument of
|
||||
* PHYSFS_addToSearchPath or any of the mount functions), not the
|
||||
* path where it is mounted in the tree (the "mountPoint" argument
|
||||
* to any of the mount functions).
|
||||
*
|
||||
* \param oldDir dir/archive to remove.
|
||||
* \return nonzero on success, zero on failure. Use
|
||||
* PHYSFS_getLastErrorCode() to obtain the specific error.
|
||||
|
@ -3188,7 +3198,7 @@ typedef struct PHYSFS_Io
|
|||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname, const char *mountPoint, int appendToPath)
|
||||
* \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *newDir, const char *mountPoint, int appendToPath)
|
||||
* \brief Add an archive, built on a PHYSFS_Io, to the search path.
|
||||
*
|
||||
* \warning Unless you have some special, low-level need, you should be using
|
||||
|
@ -3198,11 +3208,14 @@ typedef struct PHYSFS_Io
|
|||
* instead of a pathname. Behind the scenes, PHYSFS_mount() calls this
|
||||
* function with a physical-filesystem-based PHYSFS_Io.
|
||||
*
|
||||
* (filename) is only used here to optimize archiver selection (if you name it
|
||||
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
|
||||
* need to refer to a real file at all, and can even be NULL. If the filename
|
||||
* isn't helpful, the system will try every archiver until one works or none
|
||||
* of them do.
|
||||
* (newDir) must be a unique string to identify this archive. It is used
|
||||
* to optimize archiver selection (if you name it XXXXX.zip, we might try
|
||||
* the ZIP archiver first, for example, or directly choose an archiver that
|
||||
* can only trust the data is valid by filename extension). It doesn't
|
||||
* need to refer to a real file at all. If the filename extension isn't
|
||||
* helpful, the system will try every archiver until one works or none
|
||||
* of them do. This filename must be unique, as the system won't allow you
|
||||
* to have two archives with the same name.
|
||||
*
|
||||
* (io) must remain until the archive is unmounted. When the archive is
|
||||
* unmounted, the system will call (io)->destroy(io), which will give you
|
||||
|
@ -3211,7 +3224,7 @@ typedef struct PHYSFS_Io
|
|||
* If this function fails, (io)->destroy(io) is not called.
|
||||
*
|
||||
* \param io i/o instance for archive to add to the path.
|
||||
* \param fname Filename that can represent this stream. Can be NULL.
|
||||
* \param newDir Filename that can represent this stream.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
* will be "mounted", in platform-independent notation.
|
||||
* NULL or "" is equivalent to "/".
|
||||
|
@ -3224,12 +3237,12 @@ typedef struct PHYSFS_Io
|
|||
* \sa PHYSFS_getSearchPath
|
||||
* \sa PHYSFS_getMountPoint
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
||||
PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *newDir,
|
||||
const char *mountPoint, int appendToPath);
|
||||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *), const char *fname, const char *mountPoint, int appendToPath)
|
||||
* \fn int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *), const char *newDir, const char *mountPoint, int appendToPath)
|
||||
* \brief Add an archive, contained in a memory buffer, to the search path.
|
||||
*
|
||||
* \warning Unless you have some special, low-level need, you should be using
|
||||
|
@ -3239,11 +3252,14 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
* instead of a pathname. This buffer contains all the data of the archive,
|
||||
* and is used instead of a real file in the physical filesystem.
|
||||
*
|
||||
* (filename) is only used here to optimize archiver selection (if you name it
|
||||
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
|
||||
* need to refer to a real file at all, and can even be NULL. If the filename
|
||||
* isn't helpful, the system will try every archiver until one works or none
|
||||
* of them do.
|
||||
* (newDir) must be a unique string to identify this archive. It is used
|
||||
* to optimize archiver selection (if you name it XXXXX.zip, we might try
|
||||
* the ZIP archiver first, for example, or directly choose an archiver that
|
||||
* can only trust the data is valid by filename extension). It doesn't
|
||||
* need to refer to a real file at all. If the filename extension isn't
|
||||
* helpful, the system will try every archiver until one works or none
|
||||
* of them do. This filename must be unique, as the system won't allow you
|
||||
* to have two archives with the same name.
|
||||
*
|
||||
* (ptr) must remain until the archive is unmounted. When the archive is
|
||||
* unmounted, the system will call (del)(ptr), which will notify you that
|
||||
|
@ -3256,7 +3272,7 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
* \param buf Address of the memory buffer containing the archive data.
|
||||
* \param len Size of memory buffer, in bytes.
|
||||
* \param del A callback that triggers upon unmount. Can be NULL.
|
||||
* \param fname Filename that can represent this stream. Can be NULL.
|
||||
* \param newDir Filename that can represent this stream.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
* will be "mounted", in platform-independent notation.
|
||||
* NULL or "" is equivalent to "/".
|
||||
|
@ -3269,12 +3285,12 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
* \sa PHYSFS_getMountPoint
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
||||
void (*del)(void *), const char *fname,
|
||||
void (*del)(void *), const char *newDir,
|
||||
const char *mountPoint, int appendToPath);
|
||||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname, const char *mountPoint, int appendToPath)
|
||||
* \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *newDir, const char *mountPoint, int appendToPath)
|
||||
* \brief Add an archive, contained in a PHYSFS_File handle, to the search path.
|
||||
*
|
||||
* \warning Unless you have some special, low-level need, you should be using
|
||||
|
@ -3297,11 +3313,14 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
|||
* but isn't necessarily. The most popular use for this is likely to mount
|
||||
* archives stored inside other archives.
|
||||
*
|
||||
* (filename) is only used here to optimize archiver selection (if you name it
|
||||
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
|
||||
* need to refer to a real file at all, and can even be NULL. If the filename
|
||||
* isn't helpful, the system will try every archiver until one works or none
|
||||
* of them do.
|
||||
* (newDir) must be a unique string to identify this archive. It is used
|
||||
* to optimize archiver selection (if you name it XXXXX.zip, we might try
|
||||
* the ZIP archiver first, for example, or directly choose an archiver that
|
||||
* can only trust the data is valid by filename extension). It doesn't
|
||||
* need to refer to a real file at all. If the filename extension isn't
|
||||
* helpful, the system will try every archiver until one works or none
|
||||
* of them do. This filename must be unique, as the system won't allow you
|
||||
* to have two archives with the same name.
|
||||
*
|
||||
* (file) must remain until the archive is unmounted. When the archive is
|
||||
* unmounted, the system will call PHYSFS_close(file). If you need this
|
||||
|
@ -3311,7 +3330,7 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
|||
* If this function fails, PHYSFS_close(file) is not called.
|
||||
*
|
||||
* \param file The PHYSFS_File handle containing archive data.
|
||||
* \param fname Filename that can represent this stream. Can be NULL.
|
||||
* \param newDir Filename that can represent this stream.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
* will be "mounted", in platform-independent notation.
|
||||
* NULL or "" is equivalent to "/".
|
||||
|
@ -3323,7 +3342,7 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
|||
* \sa PHYSFS_getSearchPath
|
||||
* \sa PHYSFS_getMountPoint
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
|
||||
PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *newDir,
|
||||
const char *mountPoint, int appendToPath);
|
||||
|
||||
|
||||
|
|
|
@ -203,6 +203,8 @@ static void SZIP_closeArchive(void *opaque)
|
|||
SZIPinfo *info = (SZIPinfo *) opaque;
|
||||
if (info)
|
||||
{
|
||||
if (info->io)
|
||||
info->io->destroy(info->io);
|
||||
SzArEx_Free(&info->db, &SZIP_SzAlloc);
|
||||
__PHYSFS_DirTreeDeinit(&info->tree);
|
||||
allocator.Free(info);
|
||||
|
|
|
@ -49,7 +49,8 @@ static void *DIR_openArchive(PHYSFS_Io *io, const char *name,
|
|||
const size_t seplen = 1;
|
||||
|
||||
assert(io == NULL); /* shouldn't create an Io for these. */
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st), NULL);
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st, 1), NULL);
|
||||
|
||||
if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
|
||||
BAIL(PHYSFS_ERR_UNSUPPORTED, NULL);
|
||||
|
||||
|
@ -97,7 +98,7 @@ static PHYSFS_Io *doOpen(void *opaque, const char *name, const int mode)
|
|||
{
|
||||
const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
|
||||
PHYSFS_Stat statbuf;
|
||||
__PHYSFS_platformStat(f, &statbuf);
|
||||
__PHYSFS_platformStat(f, &statbuf, 0); /* !!! FIXME: why are we stating here? */
|
||||
PHYSFS_setErrorCode(err);
|
||||
} /* if */
|
||||
|
||||
|
@ -164,7 +165,7 @@ static int DIR_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
|
|||
|
||||
CVT_TO_DEPENDENT(d, opaque, name);
|
||||
BAIL_IF_ERRPASS(!d, 0);
|
||||
retval = __PHYSFS_platformStat(d, stat);
|
||||
retval = __PHYSFS_platformStat(d, stat, 0);
|
||||
__PHYSFS_smallFree(d);
|
||||
return retval;
|
||||
} /* DIR_stat */
|
||||
|
|
|
@ -151,18 +151,25 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet,
|
|||
|
||||
/* recordlen = 0 -> no more entries or fill entry */
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &recordlen, 1), 0);
|
||||
if (recordlen == 0)
|
||||
if (recordlen > 0)
|
||||
readpos += recordlen; /* ready to seek to next record. */
|
||||
else
|
||||
{
|
||||
PHYSFS_uint64 nextpos;
|
||||
|
||||
/* if we are in the last sector of the directory & it's 0 -> end */
|
||||
if ((dirend - 2048) <= (readpos - 1))
|
||||
break; /* finished */
|
||||
|
||||
/* else skip to the next sector & continue; */
|
||||
readpos = (((readpos - 1) / 2048) + 1) * 2048;
|
||||
continue;
|
||||
} /* if */
|
||||
nextpos = (((readpos - 1) / 2048) + 1) * 2048;
|
||||
|
||||
readpos += recordlen; /* ready to seek to next record. */
|
||||
/* whoops, can't make forward progress! */
|
||||
BAIL_IF(nextpos == readpos, PHYSFS_ERR_CORRUPT, 0);
|
||||
|
||||
readpos = nextpos;
|
||||
continue; /* start back at upper loop. */
|
||||
} /* else */
|
||||
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &extattrlen, 1), 0);
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &extent, 4), 0);
|
||||
|
@ -203,6 +210,10 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet,
|
|||
timestamp = (PHYSFS_sint64) mktime(&t);
|
||||
|
||||
extent += extattrlen; /* skip extended attribute record. */
|
||||
|
||||
/* infinite loop, corrupt file? */
|
||||
BAIL_IF((extent * 2048) == dirstart, PHYSFS_ERR_CORRUPT, 0);
|
||||
|
||||
if (!iso9660AddEntry(io, joliet, isdir, base, fname, fnamelen,
|
||||
timestamp, extent * 2048, datalen, unpkarc))
|
||||
{
|
||||
|
|
|
@ -455,6 +455,7 @@ static PHYSFS_Io *ZIP_duplicate(PHYSFS_Io *io)
|
|||
finfo->io = zip_get_io(origfinfo->io, NULL, finfo->entry);
|
||||
GOTO_IF_ERRPASS(!finfo->io, failed);
|
||||
|
||||
initializeZStream(&finfo->stream);
|
||||
if (finfo->entry->compression_method != COMPMETH_NONE)
|
||||
{
|
||||
finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
|
||||
|
|
|
@ -162,35 +162,44 @@ void __PHYSFS_smallFree(void *ptr);
|
|||
#define free(x) Do not use free() directly.
|
||||
/* !!! FIXME: add alloca check here. */
|
||||
|
||||
|
||||
/* by default, enable things, so builds can opt out of a few things they
|
||||
want to avoid. But you can build with this #defined to 0 if you would
|
||||
like to turn off everything except a handful of things you opt into. */
|
||||
#ifndef PHYSFS_SUPPORTS_DEFAULT
|
||||
#define PHYSFS_SUPPORTS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PHYSFS_SUPPORTS_ZIP
|
||||
#define PHYSFS_SUPPORTS_ZIP 1
|
||||
#define PHYSFS_SUPPORTS_ZIP PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_7Z
|
||||
#define PHYSFS_SUPPORTS_7Z 1
|
||||
#define PHYSFS_SUPPORTS_7Z PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_GRP
|
||||
#define PHYSFS_SUPPORTS_GRP 1
|
||||
#define PHYSFS_SUPPORTS_GRP PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_HOG
|
||||
#define PHYSFS_SUPPORTS_HOG 1
|
||||
#define PHYSFS_SUPPORTS_HOG PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_MVL
|
||||
#define PHYSFS_SUPPORTS_MVL 1
|
||||
#define PHYSFS_SUPPORTS_MVL PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_WAD
|
||||
#define PHYSFS_SUPPORTS_WAD 1
|
||||
#define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_QPAK
|
||||
#define PHYSFS_SUPPORTS_QPAK 1
|
||||
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_SLB
|
||||
#define PHYSFS_SUPPORTS_SLB 1
|
||||
#define PHYSFS_SUPPORTS_SLB PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_ISO9660
|
||||
#define PHYSFS_SUPPORTS_ISO9660 1
|
||||
#define PHYSFS_SUPPORTS_ISO9660 PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_VDF
|
||||
#define PHYSFS_SUPPORTS_VDF 1
|
||||
#define PHYSFS_SUPPORTS_VDF PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
|
||||
#if PHYSFS_SUPPORTS_7Z
|
||||
|
@ -549,11 +558,12 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
|
|||
*
|
||||
* This needs to fill in all the fields of (stat). For fields that might not
|
||||
* mean anything on a platform (access time, perhaps), choose a reasonable
|
||||
* default.
|
||||
* default. if (follow), we want to follow symlinks and stat what they
|
||||
* link to and not the link itself.
|
||||
*
|
||||
* Return zero on failure, non-zero on success.
|
||||
*/
|
||||
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat);
|
||||
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat, const int follow);
|
||||
|
||||
/*
|
||||
* Flush any pending writes to disk. (opaque) should be cast to whatever data
|
||||
|
|
|
@ -50,7 +50,7 @@ char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
|||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
|
||||
BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL);
|
||||
NSString *path = (NSString *) paths[0];
|
||||
NSString *path = (NSString *) [paths objectAtIndex:0];
|
||||
BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
|
||||
size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
const size_t applen = strlen(app);
|
||||
|
|
|
@ -721,7 +721,7 @@ PHYSFS_sint64 os2TimeToUnixTime(const FDATE *date, const FTIME *time)
|
|||
} /* os2TimeToUnixTime */
|
||||
|
||||
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *stat)
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *stat, const int follow)
|
||||
{
|
||||
char *cpfname = cvtUtf8ToCodepage(filename);
|
||||
FILESTATUS3 fs;
|
||||
|
|
|
@ -296,11 +296,11 @@ int __PHYSFS_platformDelete(const char *path)
|
|||
} /* __PHYSFS_platformDelete */
|
||||
|
||||
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
||||
int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st, const int follow)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
BAIL_IF(lstat(filename, &statbuf) == -1, errcodeFromErrno(), 0);
|
||||
const int rc = follow ? stat(fname, &statbuf) : lstat(fname, &statbuf);
|
||||
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
|
||||
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
{
|
||||
|
@ -330,7 +330,7 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
|||
st->createtime = statbuf.st_ctime;
|
||||
st->accesstime = statbuf.st_atime;
|
||||
|
||||
st->readonly = (access(filename, W_OK) == -1);
|
||||
st->readonly = (access(fname, W_OK) == -1);
|
||||
return 1;
|
||||
} /* __PHYSFS_platformStat */
|
||||
|
||||
|
|
|
@ -566,18 +566,26 @@ char *__PHYSFS_platformCalcUserDir(void)
|
|||
else
|
||||
{
|
||||
DWORD psize = 0;
|
||||
WCHAR dummy = 0;
|
||||
LPWSTR wstr = NULL;
|
||||
BOOL rc = 0;
|
||||
|
||||
/*
|
||||
* Should fail. Will write the size of the profile path in
|
||||
* psize. Also note that the second parameter can't be
|
||||
* NULL or the function fails.
|
||||
* NULL or the function fails on Windows XP, but has to be NULL on
|
||||
* Windows 10 or it will fail. :(
|
||||
*/
|
||||
rc = pGetDir(accessToken, &dummy, &psize);
|
||||
rc = pGetDir(accessToken, NULL, &psize);
|
||||
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
|
||||
|
||||
if (psize == 0) /* probably on Windows XP, try a different way. */
|
||||
{
|
||||
WCHAR x = 0;
|
||||
rc = pGetDir(accessToken, &x, &psize);
|
||||
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
|
||||
GOTO_IF(!psize, PHYSFS_ERR_OS_ERROR, done); /* Uhoh... */
|
||||
} /* if */
|
||||
|
||||
/* Allocate memory for the profile directory */
|
||||
wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR));
|
||||
if (wstr != NULL)
|
||||
|
@ -960,7 +968,7 @@ static int isSymlink(const WCHAR *wpath, const DWORD attr)
|
|||
} /* isSymlink */
|
||||
|
||||
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st, const int follow)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA winstat;
|
||||
WCHAR *wstr = NULL;
|
||||
|
@ -975,7 +983,7 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
|||
if (!rc)
|
||||
err = GetLastError();
|
||||
else /* check for symlink while wstr is still available */
|
||||
issymlink = isSymlink(wstr, winstat.dwFileAttributes);
|
||||
issymlink = !follow && isSymlink(wstr, winstat.dwFileAttributes);
|
||||
|
||||
__PHYSFS_smallFree(wstr);
|
||||
BAIL_IF(!rc, errcodeFromWinApiError(err), 0);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#define TEST_VERSION_MAJOR 3
|
||||
#define TEST_VERSION_MINOR 0
|
||||
#define TEST_VERSION_PATCH 0
|
||||
#define TEST_VERSION_PATCH 2
|
||||
|
||||
static FILE *history_file = NULL;
|
||||
static PHYSFS_uint32 do_buffer_size = 0;
|
||||
|
|
Loading…
Reference in New Issue