uio cleanups, documentation
path fixes, improvements Fixes bugs 738, 907 git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2641 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
Changes towards version 0.7:
|
Changes towards version 0.7:
|
||||||
|
- uio cleanups, documentation - SvdB
|
||||||
|
- uio path parsing fixes/improvements - SvdB
|
||||||
|
- Windows UNC path support (#907)
|
||||||
|
- Windows drive-relative paths ("D:path" without a path seperator)
|
||||||
|
- treat multiple consecutive path seperators as one (like POSIX)
|
||||||
|
- config dir no longer needs trailing path seperator (bug #738)- SvdB
|
||||||
- Simplification of uio Stream functions. No more internal seeks. - SvdB
|
- Simplification of uio Stream functions. No more internal seeks. - SvdB
|
||||||
|
|
||||||
Changes towards version 0.6:
|
Changes towards version 0.6:
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ Bugs:
|
|||||||
button won't be updated.
|
button won't be updated.
|
||||||
- If one side is computer-controlled, sync loss will occur, because the AI
|
- If one side is computer-controlled, sync loss will occur, because the AI
|
||||||
uses the RNG. It needs its own RNG context.
|
uses the RNG. It needs its own RNG context.
|
||||||
|
- Pressing F10 to exit the supermelee setup when a connection is active
|
||||||
|
will cause an attempt to draw a NULL frame. (possibly the disconnect
|
||||||
|
feedback)
|
||||||
|
|
||||||
|
|
||||||
Final actions:
|
Final actions:
|
||||||
|
|||||||
@@ -20,10 +20,10 @@
|
|||||||
#define CONFIGDIR USERDIR
|
#define CONFIGDIR USERDIR
|
||||||
|
|
||||||
/* Directory where supermelee teams will be stored */
|
/* Directory where supermelee teams will be stored */
|
||||||
#define MELEEDIR "${UQM_CONFIG_DIR}teams/"
|
#define MELEEDIR "${UQM_CONFIG_DIR}/teams/"
|
||||||
|
|
||||||
/* Directory where save games will be stored */
|
/* Directory where save games will be stored */
|
||||||
#define SAVEDIR "${UQM_CONFIG_DIR}save/"
|
#define SAVEDIR "${UQM_CONFIG_DIR}/save/"
|
||||||
|
|
||||||
/* Defined if words are stored with the most significant byte first */
|
/* Defined if words are stored with the most significant byte first */
|
||||||
@WORDS_BIGENDIAN@
|
@WORDS_BIGENDIAN@
|
||||||
|
|||||||
@@ -21,10 +21,10 @@
|
|||||||
#define CONFIGDIR USERDIR
|
#define CONFIGDIR USERDIR
|
||||||
|
|
||||||
/* Directory where supermelee teams will be stored */
|
/* Directory where supermelee teams will be stored */
|
||||||
#define MELEEDIR "%UQM_CONFIG_DIR%teams/"
|
#define MELEEDIR "%UQM_CONFIG_DIR/%teams/"
|
||||||
|
|
||||||
/* Directory where save games will be stored */
|
/* Directory where save games will be stored */
|
||||||
#define SAVEDIR "%UQM_CONFIG_DIR%save/"
|
#define SAVEDIR "%UQM_CONFIG_DIR/%save/"
|
||||||
|
|
||||||
/* Defined if words are stored with the most significant byte first */
|
/* Defined if words are stored with the most significant byte first */
|
||||||
@WORDS_BIGENDIAN@
|
@WORDS_BIGENDIAN@
|
||||||
|
|||||||
+1
-1
@@ -401,6 +401,6 @@ mountDirZips (uio_MountHandle *contentHandle, uio_DirHandle *dirHandle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uio_freeDirList (dirList);
|
uio_DirList_free (dirList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-12
@@ -19,6 +19,26 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Compilation related
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define inline __inline
|
||||||
|
#else
|
||||||
|
# define inline __inline__
|
||||||
|
# ifdef __MINGW32__
|
||||||
|
// For when including Microsoft Windows header files.
|
||||||
|
# define _inline inline
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Compilation warnings:
|
||||||
|
// UQM uses a lot of functions that can be used unsafely, but it uses them
|
||||||
|
// in a safe way. The warnings about these functions however may drown out
|
||||||
|
// serious warnings, so we turn them off.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
#else
|
#else
|
||||||
@@ -40,18 +60,6 @@ char *strupr (char *str);
|
|||||||
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
|
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Compilation related
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# define inline __inline
|
|
||||||
#else
|
|
||||||
# define inline __inline__
|
|
||||||
# ifdef __MINGW32__
|
|
||||||
// For when including Microsoft Windows header files.
|
|
||||||
# define _inline inline
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Directories
|
// Directories
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
|||||||
@@ -49,15 +49,20 @@ int expandPath (char *dest, size_t len, const char *src, int what);
|
|||||||
// Process ".." and "."
|
// Process ".." and "."
|
||||||
#define EP_SLASHES 16
|
#define EP_SLASHES 16
|
||||||
// Consider backslashes as path component separators.
|
// Consider backslashes as path component separators.
|
||||||
// They will be replaced by slashes.
|
// They will be replaced by slashes. Windows UNC paths will always
|
||||||
#define EP_ALL (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | EP_SLASHES)
|
// start with "\\server\share", with backslashes.
|
||||||
|
#define EP_SINGLESEP 32
|
||||||
|
// Replace multiple consecutive path separators by a single one.
|
||||||
|
#define EP_ALL (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | EP_SLASHES \
|
||||||
|
EP_SINGLESEP)
|
||||||
// Everything
|
// Everything
|
||||||
// Everything except Windows style backslashes on Unix Systems:
|
// Everything except Windows style backslashes on Unix Systems:
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# define EP_ALL_SYSTEM (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | \
|
# define EP_ALL_SYSTEM (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | \
|
||||||
EP_SLASHES)
|
EP_SLASHES | EP_SINGLESEP)
|
||||||
#else
|
#else
|
||||||
# define EP_ALL_SYSTEM (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS)
|
# define EP_ALL_SYSTEM (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | \
|
||||||
|
EP_SINGLESEP)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// from files.h
|
// from files.h
|
||||||
@@ -65,6 +70,9 @@ int copyFile (uio_DirHandle *srcDir, const char *srcName,
|
|||||||
uio_DirHandle *dstDir, const char *newName);
|
uio_DirHandle *dstDir, const char *newName);
|
||||||
bool fileExists (const char *name);
|
bool fileExists (const char *name);
|
||||||
bool fileExists2(uio_DirHandle *dir, const char *fileName);
|
bool fileExists2(uio_DirHandle *dir, const char *fileName);
|
||||||
|
#ifdef WIN32
|
||||||
|
size_t skipUNCServerShare(const char *inPath);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static inline int isDriveLetter(int c)
|
static inline int isDriveLetter(int c)
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
#define APPDATA_FALLBACK
|
#define APPDATA_FALLBACK
|
||||||
|
|
||||||
|
|
||||||
static char *expandPathAbsolute (char *dest, size_t destLen,
|
static char *expandPathAbsolute (char *dest, size_t destLen, const char *src,
|
||||||
const char *src, int what);
|
size_t *skipSrc, int what);
|
||||||
static char *strrchr2(const char *start, int c, const char *end);
|
static char *strrchr2(const char *start, int c, const char *end);
|
||||||
|
|
||||||
|
|
||||||
@@ -73,19 +73,56 @@ mkdirhier (const char *path)
|
|||||||
pathstart = path;
|
pathstart = path;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// driveletter + semicolon on Windows.
|
|
||||||
if (isDriveLetter(pathstart[0]) && pathstart[1] == ':')
|
if (isDriveLetter(pathstart[0]) && pathstart[1] == ':')
|
||||||
{
|
{
|
||||||
|
// Driveletter + semicolon on Windows.
|
||||||
|
// Copy as is; don't try to create directories for it.
|
||||||
*(ptr++) = *(pathstart++);
|
*(ptr++) = *(pathstart++);
|
||||||
*(ptr++) = *(pathstart++);
|
*(ptr++) = *(pathstart++);
|
||||||
|
|
||||||
|
ptr[0] = '/';
|
||||||
|
ptr[1] = '\0';
|
||||||
|
if (stat (buf, &statbuf) == -1)
|
||||||
|
{
|
||||||
|
log_add (log_Error, "Can't stat \"%s\": %s", buf, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (pathstart[0] == '\\' && pathstart[1] == '\\') {
|
||||||
|
// Windows UNC path. (\\server\share\...)
|
||||||
|
// Copy the server part as is; don't try to create directories for
|
||||||
|
// it, or stat it. Don't create a dir for the share either.
|
||||||
|
*(ptr++) = *(pathstart++);
|
||||||
|
*(ptr++) = *(pathstart++);
|
||||||
|
|
||||||
|
// Copy the server part
|
||||||
|
while (*pathstart != '\0' && *pathstart != '\\' && *pathstart != '/')
|
||||||
|
*(ptr++) = *(pathstart++);
|
||||||
|
|
||||||
|
if (*pathstart == '\0')
|
||||||
|
{
|
||||||
|
log_add (log_Error, "Incomplete UNC path \"%s\"", pathstart);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the path seperator.
|
||||||
|
*(ptr++) = *(pathstart++);
|
||||||
|
|
||||||
|
// Copy the share part
|
||||||
|
while (*pathstart != '\0' && *pathstart != '\\' && *pathstart != '/')
|
||||||
|
*(ptr++) = *(pathstart++);
|
||||||
|
|
||||||
|
ptr[0] = '/';
|
||||||
|
ptr[1] = '\0';
|
||||||
|
if (stat (buf, &statbuf) == -1)
|
||||||
|
{
|
||||||
|
log_add (log_Error, "Can't stat \"%s\": %s", buf, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (*pathstart == '/') {
|
if (*pathstart == '/')
|
||||||
*ptr = '/';
|
*(ptr++) = *(pathstart++);
|
||||||
ptr++;
|
|
||||||
pathstart++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*pathstart == '\0') {
|
if (*pathstart == '\0') {
|
||||||
// path exists completely, nothing more to do
|
// path exists completely, nothing more to do
|
||||||
@@ -106,7 +143,7 @@ mkdirhier (const char *path)
|
|||||||
{
|
{
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
{
|
{
|
||||||
log_add (log_Error, "Can't stat %s: %s", buf,
|
log_add (log_Error, "Can't stat \"%s\": %s", buf,
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -194,6 +231,8 @@ getHomeDir (void)
|
|||||||
// EP_DOTS - Process ".." and "."
|
// EP_DOTS - Process ".." and "."
|
||||||
// EP_SLASHES - Consider backslashes as path component separators.
|
// EP_SLASHES - Consider backslashes as path component separators.
|
||||||
// They will be replaced by slashes.
|
// They will be replaced by slashes.
|
||||||
|
// EP_SINGLESEP - Replace multiple consecutive path seperators (which POSIX
|
||||||
|
// considers equivalent to a single one) by a single one.
|
||||||
// Additionally, there's EP_ALL, which indicates all of the above,
|
// Additionally, there's EP_ALL, which indicates all of the above,
|
||||||
// and EP_SYSTEM_ALL, which does the same as EP_ALL, with the exception
|
// and EP_SYSTEM_ALL, which does the same as EP_ALL, with the exception
|
||||||
// of EP_SLASHES, which will only be included if the operating system
|
// of EP_SLASHES, which will only be included if the operating system
|
||||||
@@ -396,13 +435,15 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
homelen = strlen (home);
|
homelen = strlen (home);
|
||||||
|
|
||||||
if (what & EP_ABSOLUTE) {
|
if (what & EP_ABSOLUTE) {
|
||||||
|
size_t skip;
|
||||||
destptr = expandPathAbsolute (dest, destend - dest,
|
destptr = expandPathAbsolute (dest, destend - dest,
|
||||||
home, what);
|
home, &skip, what);
|
||||||
if (destptr == NULL)
|
if (destptr == NULL)
|
||||||
{
|
{
|
||||||
// errno is set
|
// errno is set
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
home += skip;
|
||||||
what &= ~EP_ABSOLUTE;
|
what &= ~EP_ABSOLUTE;
|
||||||
// The part after the '~' should not be seen
|
// The part after the '~' should not be seen
|
||||||
// as absolute.
|
// as absolute.
|
||||||
@@ -417,13 +458,15 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
|
|
||||||
if (what & EP_ABSOLUTE)
|
if (what & EP_ABSOLUTE)
|
||||||
{
|
{
|
||||||
|
size_t skip;
|
||||||
destptr = expandPathAbsolute (destptr, destend - destptr, src,
|
destptr = expandPathAbsolute (destptr, destend - destptr, src,
|
||||||
what);
|
&skip, what);
|
||||||
if (destptr == NULL)
|
if (destptr == NULL)
|
||||||
{
|
{
|
||||||
// errno is set
|
// errno is set
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
src += skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKLEN (dest, srcend - src);
|
CHECKLEN (dest, srcend - src);
|
||||||
@@ -435,6 +478,20 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
{
|
{
|
||||||
/* Replacing backslashes in path by slashes. */
|
/* Replacing backslashes in path by slashes. */
|
||||||
destptr = dest;
|
destptr = dest;
|
||||||
|
#ifdef WIN32
|
||||||
|
{
|
||||||
|
// A Windows UNC path should always start with two backslashes
|
||||||
|
// and have a backslash in between the server and share part.
|
||||||
|
size_t skip = skipUNCServerShare (destptr);
|
||||||
|
if (skip != 0)
|
||||||
|
{
|
||||||
|
char *slash = (char *) memchr (destptr + 2, '/', skip - 2);
|
||||||
|
if (slash)
|
||||||
|
*slash = '\\';
|
||||||
|
destptr += skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
while (*destptr != '\0')
|
while (*destptr != '\0')
|
||||||
{
|
{
|
||||||
if (*destptr == '\\')
|
if (*destptr == '\\')
|
||||||
@@ -456,8 +513,15 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
|
|
||||||
pathStart = dest;
|
pathStart = dest;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (isDriveLetter(src[0]) && (src[1] == ':'))
|
if (isDriveLetter(pathStart[0]) && (pathStart[1] == ':'))
|
||||||
|
{
|
||||||
pathStart += 2;
|
pathStart += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Test for a UNC path.
|
||||||
|
pathStart += skipUNCServerShare(pathStart);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (pathStart[0] == '/')
|
if (pathStart[0] == '/')
|
||||||
pathStart++;
|
pathStart++;
|
||||||
@@ -517,34 +581,113 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
*destptr = '\0';
|
*destptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (what & EP_SINGLESEP)
|
||||||
|
{
|
||||||
|
char *srcptr;
|
||||||
|
srcptr = dest;
|
||||||
|
destptr = dest;
|
||||||
|
while (*srcptr != '\0')
|
||||||
|
{
|
||||||
|
char ch = *srcptr;
|
||||||
|
*(destptr++) = *(srcptr++);
|
||||||
|
if (ch == '/')
|
||||||
|
{
|
||||||
|
while (*srcptr == '/')
|
||||||
|
srcptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*destptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
// letter is 0 based: 0 = A, 1 = B, ...
|
||||||
|
bool
|
||||||
|
driveLetterExists(int letter)
|
||||||
|
{
|
||||||
|
unsigned long drives;
|
||||||
|
|
||||||
|
drives = _getdrives ();
|
||||||
|
|
||||||
|
return ((drives >> letter) & 1) != 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// helper for expandPath, expanding an absolute path
|
// helper for expandPath, expanding an absolute path
|
||||||
// returns a pointer to the end of the filled in part of dest.
|
// returns a pointer to the end of the filled in part of dest.
|
||||||
static char *
|
static char *
|
||||||
expandPathAbsolute (char *dest, size_t destLen, const char *src, int what)
|
expandPathAbsolute (char *dest, size_t destLen, const char *src,
|
||||||
|
size_t *skipSrc, int what)
|
||||||
{
|
{
|
||||||
if (src[0] == '/' || ((what & EP_SLASHES) && src[0] == '\\')
|
const char *orgSrc;
|
||||||
#ifdef WIN32
|
|
||||||
|| (isDriveLetter(src[0]) && (src[1] == ':'))
|
if (src[0] == '/' || ((what & EP_SLASHES) && src[0] == '\\'))
|
||||||
#endif
|
{
|
||||||
) {
|
|
||||||
// Path is already absolute; nothing to do
|
// Path is already absolute; nothing to do
|
||||||
|
*skipSrc = 0;
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path is not already absolute; we've got work to do.
|
orgSrc = src;
|
||||||
if (getcwd (dest, destLen) == NULL)
|
#ifdef WIN32
|
||||||
|
if (isDriveLetter(src[0]) && (src[1] == ':'))
|
||||||
|
{
|
||||||
|
int letter;
|
||||||
|
|
||||||
|
if (src[2] == '/' || src[2] == '\\')
|
||||||
|
{
|
||||||
|
// Path is already absolute (of the form "d:/"); nothing to do
|
||||||
|
*skipSrc = 0;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path is of the form "d:path", without a (back)slash after the
|
||||||
|
// semicolon.
|
||||||
|
|
||||||
|
letter = tolower(src[0]) - 'a';
|
||||||
|
|
||||||
|
// _getdcwd() should only be called on drives that exist.
|
||||||
|
// This is weird though, because it means a race condition
|
||||||
|
// in between the existance check and the call to _getdcwd()
|
||||||
|
// cannot be avoided, unless a drive still exists for Windows
|
||||||
|
// when the physical drive is removed.
|
||||||
|
if (!driveLetterExists(letter))
|
||||||
|
{
|
||||||
|
errno = ENOENT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the working directory for a specific drive.
|
||||||
|
if (_getdcwd (letter + 1, dest, destLen) == NULL)
|
||||||
{
|
{
|
||||||
// errno is set
|
// errno is set
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Relative dir
|
||||||
|
if (getcwd (dest, destLen) == NULL)
|
||||||
|
{
|
||||||
|
// errno is set
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t tempLen;
|
size_t tempLen;
|
||||||
tempLen = strlen (dest);
|
tempLen = strlen (dest);
|
||||||
assert (tempLen > 0);
|
if (tempLen == 0)
|
||||||
|
{
|
||||||
|
// getcwd() or _getdcwd() returned a 0-length string.
|
||||||
|
errno = ENOENT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
dest += tempLen;
|
dest += tempLen;
|
||||||
destLen -= tempLen;
|
destLen -= tempLen;
|
||||||
}
|
}
|
||||||
@@ -561,6 +704,8 @@ expandPathAbsolute (char *dest, size_t destLen, const char *src, int what)
|
|||||||
dest++;
|
dest++;
|
||||||
destLen--;
|
destLen--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*skipSrc = (size_t) (src - orgSrc);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,4 +721,34 @@ strrchr2(const char *start, int c, const char *end) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
// returns 0 if the path is not a valid UNC path.
|
||||||
|
// Does not skip trailing slashes.
|
||||||
|
size_t
|
||||||
|
skipUNCServerShare(const char *inPath) {
|
||||||
|
const char *path = inPath;
|
||||||
|
|
||||||
|
// Skip the initial two backslashes.
|
||||||
|
if (path[0] != '\\' || path[1] != '\\')
|
||||||
|
return (size_t) 0;
|
||||||
|
path += 2;
|
||||||
|
|
||||||
|
// Skip the server part.
|
||||||
|
while (*path != '\\' && *path != '/') {
|
||||||
|
if (*path == '\0')
|
||||||
|
return (size_t) 0;
|
||||||
|
path++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the seperator.
|
||||||
|
path++;
|
||||||
|
|
||||||
|
// Skip the share part.
|
||||||
|
while (*path != '\0' && *path != '\\' && *path != '/')
|
||||||
|
path++;
|
||||||
|
|
||||||
|
return (size_t) (path - inPath);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ LoadDirEntryTable (uio_DirHandle *dirHandle, const char *path,
|
|||||||
uio_closeDir (dir);
|
uio_closeDir (dir);
|
||||||
|
|
||||||
if (num_entries == 0) {
|
if (num_entries == 0) {
|
||||||
uio_freeDirList(dirList);
|
uio_DirList_free(dirList);
|
||||||
*pnum_entries = 0;
|
*pnum_entries = 0;
|
||||||
return ((DIRENTRY_REF) 0);
|
return ((DIRENTRY_REF) 0);
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ LoadDirEntryTable (uio_DirHandle *dirHandle, const char *path,
|
|||||||
if (lpST == 0)
|
if (lpST == 0)
|
||||||
{
|
{
|
||||||
FreeStringTable (StringTable);
|
FreeStringTable (StringTable);
|
||||||
uio_freeDirList(dirList);
|
uio_DirList_free(dirList);
|
||||||
*pnum_entries = 0;
|
*pnum_entries = 0;
|
||||||
return ((DIRENTRY_REF) 0);
|
return ((DIRENTRY_REF) 0);
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ LoadDirEntryTable (uio_DirHandle *dirHandle, const char *path,
|
|||||||
lpStr += size;
|
lpStr += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uio_freeDirList(dirList);
|
uio_DirList_free(dirList);
|
||||||
*pnum_entries = num_entries;
|
*pnum_entries = num_entries;
|
||||||
UnlockStringTable (StringTable);
|
UnlockStringTable (StringTable);
|
||||||
return ((DIRENTRY_REF) StringTable);
|
return ((DIRENTRY_REF) StringTable);
|
||||||
|
|||||||
@@ -712,7 +712,7 @@ listOneDir(DebugContext *debugContext, const char *arg) {
|
|||||||
}
|
}
|
||||||
for (i = 0; i < dirList->numNames; i++)
|
for (i = 0; i < dirList->numNames; i++)
|
||||||
fprintf(debugContext->out, "%s\n", dirList->names[i]);
|
fprintf(debugContext->out, "%s\n", dirList->names[i]);
|
||||||
uio_freeDirList(dirList);
|
uio_DirList_free(dirList);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Documentation:
|
|||||||
- It would be (theoretically) possible to add HTTP and FTP support for
|
- It would be (theoretically) possible to add HTTP and FTP support for
|
||||||
remote file systems.
|
remote file systems.
|
||||||
- on adding extra file system types:
|
- on adding extra file system types:
|
||||||
- open, mkdir, rmdir, and unlink should themselves make sure that
|
open, mkdir, rmdir, and unlink should themselves make sure that
|
||||||
the physical structure is kept up to date when an entry is
|
the physical structure is kept up to date when an entry is
|
||||||
removed or added.
|
removed or added.
|
||||||
- stream stuff is not thread safe
|
- stream stuff is not thread safe
|
||||||
@@ -36,7 +36,7 @@ Bugs:
|
|||||||
in the dirHandle, which will cause problems.
|
in the dirHandle, which will cause problems.
|
||||||
- 'openDirRelative(repository, "/")' causes segfaults later on
|
- 'openDirRelative(repository, "/")' causes segfaults later on
|
||||||
- uio_rename() doesn't work on directories
|
- uio_rename() doesn't work on directories
|
||||||
uio_getPhysicalAccess() needs to be changed so that it works the same on
|
- uio_getPhysicalAccess() needs to be changed so that it works the same on
|
||||||
dirs as on files. stat() can be cleaned up too then.
|
dirs as on files. stat() can be cleaned up too then.
|
||||||
- uio_getPhysicalAccess() will not return ENOENT when (only) the last
|
- uio_getPhysicalAccess() will not return ENOENT when (only) the last
|
||||||
component does not exist, even when O_RDONLY is used.
|
component does not exist, even when O_RDONLY is used.
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
static uio_FileBlock *uio_FileBlock_new(uio_Handle *handle, int flags,
|
static uio_FileBlock *uio_FileBlock_new(uio_Handle *handle, int flags,
|
||||||
off_t offset, size_t blockSize, char *buffer, size_t bufSize);
|
off_t offset, size_t blockSize, char *buffer, size_t bufSize);
|
||||||
static inline uio_FileBlock *uio_FileBlock_alloc(void);
|
static inline uio_FileBlock *uio_FileBlock_alloc(void);
|
||||||
static void uio_freeFileBlock(uio_FileBlock *block);
|
static void uio_FileBlock_free(uio_FileBlock *block);
|
||||||
|
|
||||||
|
|
||||||
uio_FileBlock *
|
uio_FileBlock *
|
||||||
@@ -150,11 +150,11 @@ uio_closeFileBlock(uio_FileBlock *block) {
|
|||||||
uio_free(block->buffer);
|
uio_free(block->buffer);
|
||||||
}
|
}
|
||||||
uio_Handle_unref(block->handle);
|
uio_Handle_unref(block->handle);
|
||||||
uio_freeFileBlock(block);
|
uio_FileBlock_free(block);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// caller should uio_refHandle(handle) (unless it doesn't need it's own
|
// caller should uio_Handle_ref(handle) (unless it doesn't need it's own
|
||||||
// reference anymore).
|
// reference anymore).
|
||||||
static uio_FileBlock *
|
static uio_FileBlock *
|
||||||
uio_FileBlock_new(uio_Handle *handle, int flags, off_t offset,
|
uio_FileBlock_new(uio_Handle *handle, int flags, off_t offset,
|
||||||
@@ -177,7 +177,7 @@ uio_FileBlock_alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uio_freeFileBlock(uio_FileBlock *block) {
|
uio_FileBlock_free(uio_FileBlock *block) {
|
||||||
uio_free(block);
|
uio_free(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ static uio_FileSystemInfo **uio_getFileSystemInfoPtr(uio_FileSystemID id);
|
|||||||
|
|
||||||
static inline uio_FileSystemInfo *uio_FileSystemInfo_alloc(void);
|
static inline uio_FileSystemInfo *uio_FileSystemInfo_alloc(void);
|
||||||
|
|
||||||
static inline void uio_freeFileSystemInfo(uio_FileSystemInfo *fileSystemInfo);
|
static inline void uio_FileSystemInfo_free(
|
||||||
|
uio_FileSystemInfo *fileSystemInfo);
|
||||||
|
|
||||||
|
|
||||||
uio_FileSystemInfo *uio_fileSystems = NULL;
|
uio_FileSystemInfo *uio_fileSystems = NULL;
|
||||||
@@ -173,9 +174,9 @@ uio_unRegisterFileSystem(uio_FileSystemID id) {
|
|||||||
temp = *ptr;
|
temp = *ptr;
|
||||||
*ptr = (*ptr)->next;
|
*ptr = (*ptr)->next;
|
||||||
|
|
||||||
// uio_unrefFileSystemHandler(temp->handler);
|
// uio_FileSystemHandler_unref(temp->handler);
|
||||||
uio_free(temp->name);
|
uio_free(temp->name);
|
||||||
uio_freeFileSystemInfo(temp);
|
uio_FileSystemInfo_free(temp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -261,7 +262,7 @@ uio_FileSystemInfo_alloc(void) {
|
|||||||
// *** Deallocators ***
|
// *** Deallocators ***
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
uio_freeFileSystemInfo(uio_FileSystemInfo *fileSystemInfo) {
|
uio_FileSystemInfo_free(uio_FileSystemInfo *fileSystemInfo) {
|
||||||
#ifdef uio_MEM_DEBUG
|
#ifdef uio_MEM_DEBUG
|
||||||
uio_MemDebug_debugFree(uio_FileSystemInfo, (void *) fileSystemInfo);
|
uio_MemDebug_debugFree(uio_FileSystemInfo, (void *) fileSystemInfo);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ uio_unmountDir(uio_MountHandle *mountHandle) {
|
|||||||
uio_repositoryRemoveMount(mountHandle->repository,
|
uio_repositoryRemoveMount(mountHandle->repository,
|
||||||
mountHandle->mountInfo);
|
mountHandle->mountInfo);
|
||||||
|
|
||||||
uio_deleteMountInfo(mountHandle->mountInfo);
|
uio_MountInfo_delete(mountHandle->mountInfo);
|
||||||
|
|
||||||
uio_MountHandle_delete(mountHandle);
|
uio_MountHandle_delete(mountHandle);
|
||||||
uio_PRoot_unrefMount(pRoot);
|
uio_PRoot_unrefMount(pRoot);
|
||||||
@@ -643,7 +643,7 @@ uio_open(uio_DirHandle *dir, const char *path, int flags, mode_t mode) {
|
|||||||
uio_DirHandle *
|
uio_DirHandle *
|
||||||
uio_openDir(uio_Repository *repository, const char *path, int flags) {
|
uio_openDir(uio_Repository *repository, const char *path, int flags) {
|
||||||
uio_DirHandle *dirHandle;
|
uio_DirHandle *dirHandle;
|
||||||
const char * const rootStr = "/";
|
const char * const rootStr = "";
|
||||||
|
|
||||||
dirHandle = uio_DirHandle_new(repository,
|
dirHandle = uio_DirHandle_new(repository,
|
||||||
unconst(rootStr), unconst(rootStr));
|
unconst(rootStr), unconst(rootStr));
|
||||||
@@ -1009,8 +1009,8 @@ typedef struct uio_DirBufferLink {
|
|||||||
} uio_DirBufferLink;
|
} uio_DirBufferLink;
|
||||||
|
|
||||||
static int strPtrCmp(const char * const *ptr1, const char * const *ptr2);
|
static int strPtrCmp(const char * const *ptr1, const char * const *ptr2);
|
||||||
static void uio_freeDirBufferLink(uio_DirBufferLink *sdbl);
|
static void uio_DirBufferLink_free(uio_DirBufferLink *sdbl);
|
||||||
static void uio_freeDirBufferChain(uio_DirBufferLink *dirBufferLink);
|
static void uio_DirBufferChain_free(uio_DirBufferLink *dirBufferLink);
|
||||||
static uio_DirList *uio_getDirListMulti(uio_PDirHandle **pDirHandles,
|
static uio_DirList *uio_getDirListMulti(uio_PDirHandle **pDirHandles,
|
||||||
int numPDirHandles, const char *pattern, match_MatchType matchType);
|
int numPDirHandles, const char *pattern, match_MatchType matchType);
|
||||||
static uio_DirList *uio_makeDirList(const char **newNames,
|
static uio_DirList *uio_makeDirList(const char **newNames,
|
||||||
@@ -1037,7 +1037,7 @@ static inline void uio_EntriesContext_free(uio_EntriesContext
|
|||||||
|
|
||||||
// The caller may modify the elements of dirHandle->names, but
|
// The caller may modify the elements of dirHandle->names, but
|
||||||
// dirHandle->names itself, and the rest of the elements of dirHandle
|
// dirHandle->names itself, and the rest of the elements of dirHandle
|
||||||
// should be left alone, so that they will be freed by uio_freeDirList().
|
// should be left alone, so that they will be freed by uio_DirList_free().
|
||||||
uio_DirList *
|
uio_DirList *
|
||||||
uio_getDirList(uio_DirHandle *dirHandle, const char *path, const char *pattern,
|
uio_getDirList(uio_DirHandle *dirHandle, const char *path, const char *pattern,
|
||||||
match_MatchType matchType) {
|
match_MatchType matchType) {
|
||||||
@@ -1182,7 +1182,7 @@ uio_getDirListMulti(uio_PDirHandle **pDirHandles,
|
|||||||
|
|
||||||
// free the old junk
|
// free the old junk
|
||||||
for (pDirI = 0; pDirI < numPDirHandles; pDirI++)
|
for (pDirI = 0; pDirI < numPDirHandles; pDirI++)
|
||||||
uio_freeDirBufferChain(links[pDirI]);
|
uio_DirBufferChain_free(links[pDirI]);
|
||||||
uio_free(links);
|
uio_free(links);
|
||||||
uio_free(numNames);
|
uio_free(numNames);
|
||||||
|
|
||||||
@@ -1252,7 +1252,7 @@ uio_collectDirEntries(uio_PDirHandle *pDirHandle, uio_DirBufferLink **linkPtr,
|
|||||||
if (numRead == 0) {
|
if (numRead == 0) {
|
||||||
fprintf(stderr, "Warning: uio_DIR_BUFFER_SIZE is too small to "
|
fprintf(stderr, "Warning: uio_DIR_BUFFER_SIZE is too small to "
|
||||||
"hold a certain large entry on its own!\n");
|
"hold a certain large entry on its own!\n");
|
||||||
uio_freeDirBufferLink(*linkEndPtr);
|
uio_DirBufferLink_free(*linkEndPtr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
totalEntries += numRead;
|
totalEntries += numRead;
|
||||||
@@ -1356,18 +1356,18 @@ uio_EntriesContext_free(uio_EntriesContext *entriesContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uio_freeDirBufferLink(uio_DirBufferLink *dirBufferLink) {
|
uio_DirBufferLink_free(uio_DirBufferLink *dirBufferLink) {
|
||||||
uio_free(dirBufferLink->buffer);
|
uio_free(dirBufferLink->buffer);
|
||||||
uio_free(dirBufferLink);
|
uio_free(dirBufferLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uio_freeDirBufferChain(uio_DirBufferLink *dirBufferLink) {
|
uio_DirBufferChain_free(uio_DirBufferLink *dirBufferLink) {
|
||||||
uio_DirBufferLink *next;
|
uio_DirBufferLink *next;
|
||||||
|
|
||||||
while (dirBufferLink != NULL) {
|
while (dirBufferLink != NULL) {
|
||||||
next = dirBufferLink->next;
|
next = dirBufferLink->next;
|
||||||
uio_freeDirBufferLink(dirBufferLink);
|
uio_DirBufferLink_free(dirBufferLink);
|
||||||
dirBufferLink = next;
|
dirBufferLink = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1389,7 +1389,7 @@ uio_DirList_alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uio_freeDirList(uio_DirList *dirList) {
|
uio_DirList_free(uio_DirList *dirList) {
|
||||||
if (dirList->buffer)
|
if (dirList->buffer)
|
||||||
uio_free(dirList->buffer);
|
uio_free(dirList->buffer);
|
||||||
if (dirList->names)
|
if (dirList->names)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ int uio_closeDir(uio_DirHandle *dirHandle);
|
|||||||
|
|
||||||
uio_DirList *uio_getDirList(uio_DirHandle *dirHandle, const char *path,
|
uio_DirList *uio_getDirList(uio_DirHandle *dirHandle, const char *path,
|
||||||
const char *pattern, match_MatchType matchType);
|
const char *pattern, match_MatchType matchType);
|
||||||
void uio_freeDirList(uio_DirList *dirList);
|
void uio_DirList_free(uio_DirList *dirList);
|
||||||
|
|
||||||
// For debugging purposes
|
// For debugging purposes
|
||||||
void uio_DirHandle_print(const uio_DirHandle *dirHandle, FILE *out);
|
void uio_DirHandle_print(const uio_DirHandle *dirHandle, FILE *out);
|
||||||
|
|||||||
@@ -33,17 +33,30 @@ static int copyError(int error,
|
|||||||
uio_FileSystemHandler *toHandler, uio_Handle *toHandle,
|
uio_FileSystemHandler *toHandler, uio_Handle *toHandle,
|
||||||
uio_PDirHandle *toDir, const char *toName, char *buf);
|
uio_PDirHandle *toDir, const char *toName, char *buf);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Follow a path starting from a specified physical dir as long as possible.
|
* Follow a path starting from a specified physical dir for as long as
|
||||||
* When you can get no further, 'endPDirHandle' will be filled in with a
|
* possible.
|
||||||
* reference to the dir where you ended up, and 'pathRest' will point into
|
*
|
||||||
* the original path to the beginning of the part that was not matched.
|
* @param[in] startPDirHandle The physical dir to start from.
|
||||||
* It is allowed to have endPDirHandle point to pDirHandle and/or restPath
|
* @param[in] path The path to follow, relative to
|
||||||
* point to path when calling this function. Just take care to keep a
|
* 'startPDirHandle'.
|
||||||
* reference to the original so you can decrement the ref counter.
|
* @param[in] pathLen The string length of 'path'.
|
||||||
* returns: 0 if the complete path was matched
|
* @param[out] endPDirHandle The physical dir where you end up after
|
||||||
* ENOENT if some component (the next one) didn't exists
|
* following 'path' for as long as possible. Unmodified if an error
|
||||||
* ENODIR if a component (the next one) exists but isn't a dir
|
* occurs.
|
||||||
|
* @param[out] pathRest '*pathRest' will point into 'path' to the
|
||||||
|
* start the part that was not matched. Unmodified if an error occurs.
|
||||||
|
*
|
||||||
|
* @retval 0 if the complete path was matched
|
||||||
|
* @retval ENOENT if some component (the next one in '*pathRest') didn't
|
||||||
|
* exist.
|
||||||
|
* @retval ENODIR if a component (the next one in '*pathRest') did exist,
|
||||||
|
* but wasn't a dir.
|
||||||
|
*
|
||||||
|
* @note It is allowed to have 'endPDirHandle' point to pDirHandle, but
|
||||||
|
* care should be taken to keep a reference to the original so its
|
||||||
|
* reference counter can be decremented.
|
||||||
|
* @note It is allowed to have 'pathRest' point to 'path'.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
uio_walkPhysicalPath(uio_PDirHandle *startPDirHandle, const char *path,
|
uio_walkPhysicalPath(uio_PDirHandle *startPDirHandle, const char *path,
|
||||||
@@ -61,7 +74,7 @@ uio_walkPhysicalPath(uio_PDirHandle *startPDirHandle, const char *path,
|
|||||||
tempBuf = uio_alloca(strlen(path) + 1);
|
tempBuf = uio_alloca(strlen(path) + 1);
|
||||||
pathEnd = path + pathLen;
|
pathEnd = path + pathLen;
|
||||||
getFirstPathComponent(path, pathEnd, &partStart, &partEnd);
|
getFirstPathComponent(path, pathEnd, &partStart, &partEnd);
|
||||||
while (1) {
|
for (;;) {
|
||||||
if (partStart == pathEnd) {
|
if (partStart == pathEnd) {
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
break;
|
break;
|
||||||
@@ -89,7 +102,19 @@ uio_walkPhysicalPath(uio_PDirHandle *startPDirHandle, const char *path,
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a all directory components of a path, inside a physical directory.
|
/**
|
||||||
|
* Create a directory inside a physical directory. All non-existant
|
||||||
|
* parent directories will be created as well.
|
||||||
|
*
|
||||||
|
* @param[in] pDirHandle The physical directory to which 'path' is relative
|
||||||
|
* @param[in] path The path to the directory to create, relative to
|
||||||
|
* 'pDirHandle'
|
||||||
|
* @param[in] pathLen The string length of 'path'.
|
||||||
|
* @param[in] mode The access mode for the newly created directories.
|
||||||
|
*
|
||||||
|
* @returns the new (physical) directory, or NULL if an error occurs, in
|
||||||
|
* which case #errno will be set.
|
||||||
|
*/
|
||||||
uio_PDirHandle *
|
uio_PDirHandle *
|
||||||
uio_makePath(uio_PDirHandle *pDirHandle, const char *path, size_t pathLen,
|
uio_makePath(uio_PDirHandle *pDirHandle, const char *path, size_t pathLen,
|
||||||
mode_t mode) {
|
mode_t mode) {
|
||||||
@@ -136,12 +161,23 @@ uio_makePath(uio_PDirHandle *pDirHandle, const char *path, size_t pathLen,
|
|||||||
return pDirHandle;
|
return pDirHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* permissions should already have been checked
|
/**
|
||||||
|
* Copy a file from one physical directory to another.
|
||||||
|
* The copy will have the same file permissions as the original.
|
||||||
*
|
*
|
||||||
* The new file will have the same permissions as the old.
|
* @param[in] fromDir The physical directory where the file to copy is
|
||||||
* If an error occurs during copying, an attempt will be made to
|
* located.
|
||||||
* remove the copy.
|
* @param[in] fromName The name of the file to copy.
|
||||||
|
* @param[in] toDir The physical directory where to put the copy.
|
||||||
|
* @param[in] toName The name to use for the copy.
|
||||||
|
*
|
||||||
|
* @note It is up to the caller to make any relevant permissions checks.
|
||||||
|
*
|
||||||
|
* @note This function will fail if a file with the name in 'toName' already
|
||||||
|
* exists, leaving the original file intact. If an error occurs during
|
||||||
|
* copying, an attempt is made to remove the file that was to be the
|
||||||
|
* copy.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName,
|
uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName,
|
||||||
@@ -683,7 +719,7 @@ uio_verifyPath(uio_DirHandle *dirHandle, const char *path,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try all the MountInfo structures in effect for this MountTree
|
// Try all the MountInfo structures in effect for this MountTree.
|
||||||
for (item = tree->pLocs; item != NULL; item = item->next) {
|
for (item = tree->pLocs; item != NULL; item = item->next) {
|
||||||
const char *pRootPath;
|
const char *pRootPath;
|
||||||
uio_PDirHandle *pDirHandle;
|
uio_PDirHandle *pDirHandle;
|
||||||
@@ -695,7 +731,7 @@ uio_verifyPath(uio_DirHandle *dirHandle, const char *path,
|
|||||||
uio_PDirHandle_unref(pDirHandle);
|
uio_PDirHandle_unref(pDirHandle);
|
||||||
switch (retVal) {
|
switch (retVal) {
|
||||||
case 0:
|
case 0:
|
||||||
// complete match. We're done.
|
// Complete match. We're done.
|
||||||
return 0;
|
return 0;
|
||||||
case ENOTDIR:
|
case ENOTDIR:
|
||||||
// A component is matched, but not as a dir. Failed.
|
// A component is matched, but not as a dir. Failed.
|
||||||
@@ -703,7 +739,7 @@ uio_verifyPath(uio_DirHandle *dirHandle, const char *path,
|
|||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
return -1;
|
return -1;
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
// no match; try next pLoc
|
// No match; try the next pLoc.
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
// Unknown error. Let's bail out just to be safe.
|
// Unknown error. Let's bail out just to be safe.
|
||||||
@@ -723,12 +759,21 @@ uio_verifyPath(uio_DirHandle *dirHandle, const char *path,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the absolute path pointed to by 'path' relative to 'dirHandle'
|
/**
|
||||||
// The new path will be put in '*destPath', which will be newly allocated.
|
* Determine the absolute path given a path relative to a given directory.
|
||||||
// It will be \0-terminated, and will not have a '/' as first or last
|
*
|
||||||
// character.
|
* @param[in] dirHandle The directory to which 'path' is relative.
|
||||||
// The length of '*destPath' will be returned.
|
* @param[in] path The path, relative to 'dirHandle', to make
|
||||||
// On error, -1 will be returned, and errno will be set.
|
* absolute.
|
||||||
|
* @param[in] pathLen The string length of 'path'.
|
||||||
|
* @param[out] destPath Filled with a newly allocated string containing
|
||||||
|
* the sought absolute path. It will not contain a '/' as the first
|
||||||
|
* or last character. It should be freed with uio_free().
|
||||||
|
* Unmodified if an error occurs.
|
||||||
|
*
|
||||||
|
* @returns the length of '*destPath', or -1 if an error occurs, in which
|
||||||
|
* case #errno will be set.
|
||||||
|
*/
|
||||||
ssize_t
|
ssize_t
|
||||||
uio_resolvePath(uio_DirHandle *dirHandle, const char *path, size_t pathLen,
|
uio_resolvePath(uio_DirHandle *dirHandle, const char *path, size_t pathLen,
|
||||||
char **destPath) {
|
char **destPath) {
|
||||||
|
|||||||
@@ -48,6 +48,15 @@ uio_strdup(const char *s) {
|
|||||||
# define uio_strdup strdup
|
# define uio_strdup strdup
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Allocates new memory, copies 'len' characters from 'src', and adds a '\0'.
|
||||||
|
static inline char *
|
||||||
|
uio_memdup0(const char *src, size_t len) {
|
||||||
|
char *dst = uio_malloc(len + 1);
|
||||||
|
memcpy(dst, src, len);
|
||||||
|
dst[len] = '\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@
|
|||||||
# include "memdebug.h"
|
# include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void uio_deleteRepository(uio_Repository *repository);
|
static void uio_Repository_delete(uio_Repository *repository);
|
||||||
static uio_Repository *uio_Repository_alloc(void);
|
static uio_Repository *uio_Repository_alloc(void);
|
||||||
static void uio_freeRepository(uio_Repository *repository);
|
static void uio_Repository_free(uio_Repository *repository);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -137,7 +137,7 @@ uio_Repository_unref(uio_Repository *repository) {
|
|||||||
assert(repository->ref > 0);
|
assert(repository->ref > 0);
|
||||||
repository->ref--;
|
repository->ref--;
|
||||||
if (repository->ref == 0)
|
if (repository->ref == 0)
|
||||||
uio_deleteRepository(repository);
|
uio_Repository_delete(repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uio_Repository *
|
static uio_Repository *
|
||||||
@@ -150,15 +150,15 @@ uio_Repository_alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uio_deleteRepository(uio_Repository *repository) {
|
uio_Repository_delete(uio_Repository *repository) {
|
||||||
assert(repository->numMounts == 0);
|
assert(repository->numMounts == 0);
|
||||||
uio_free(repository->mounts);
|
uio_free(repository->mounts);
|
||||||
uio_deleteMountTree(repository->mountTree);
|
uio_MountTree_delete(repository->mountTree);
|
||||||
uio_freeRepository(repository);
|
uio_Repository_free(repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uio_freeRepository(uio_Repository *repository) {
|
uio_Repository_free(uio_Repository *repository) {
|
||||||
#ifdef uio_MEM_DEBUG
|
#ifdef uio_MEM_DEBUG
|
||||||
uio_MemDebug_debugFree(uio_Repository, (void *) repository);
|
uio_MemDebug_debugFree(uio_Repository, (void *) repository);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -63,10 +63,6 @@ static uio_MountTree * uio_splitMountTree(uio_MountTree **tree, uio_PathComp
|
|||||||
*lastComp, int depth);
|
*lastComp, int depth);
|
||||||
static void uio_mountTreeRemoveMountInfoRec(uio_MountTree *mountTree,
|
static void uio_mountTreeRemoveMountInfoRec(uio_MountTree *mountTree,
|
||||||
uio_MountInfo *mountInfo);
|
uio_MountInfo *mountInfo);
|
||||||
static int uio_countPathComps(const uio_PathComp *comp);
|
|
||||||
static uio_PathComp *uio_lastPathComp(uio_PathComp *comp);
|
|
||||||
static uio_PathComp *uio_makePathComps(const char *path,
|
|
||||||
uio_PathComp *upComp);
|
|
||||||
static void uio_printMount(FILE *outStream, const uio_MountInfo *mountInfo);
|
static void uio_printMount(FILE *outStream, const uio_MountInfo *mountInfo);
|
||||||
|
|
||||||
static inline uio_MountTree * uio_MountTree_new(uio_MountTree *subTrees,
|
static inline uio_MountTree * uio_MountTree_new(uio_MountTree *subTrees,
|
||||||
@@ -74,21 +70,16 @@ static inline uio_MountTree * uio_MountTree_new(uio_MountTree *subTrees,
|
|||||||
*comps, uio_PathComp *lastComp, uio_MountTree *next);
|
*comps, uio_PathComp *lastComp, uio_MountTree *next);
|
||||||
static inline uio_MountTreeItem *uio_MountTree_newItem(
|
static inline uio_MountTreeItem *uio_MountTree_newItem(
|
||||||
uio_MountInfo *mountInfo, int depth, uio_MountTreeItem *next);
|
uio_MountInfo *mountInfo, int depth, uio_MountTreeItem *next);
|
||||||
static inline uio_PathComp *uio_PathComp_new(char *name, size_t nameLen,
|
|
||||||
uio_PathComp *upComp);
|
|
||||||
|
|
||||||
static inline void uio_deleteMountTreeItem(uio_MountTreeItem *item);
|
static inline void uio_MountTreeItem_delete(uio_MountTreeItem *item);
|
||||||
static inline void uio_deletePathComp(uio_PathComp *pathComp);
|
|
||||||
|
|
||||||
static inline uio_MountTree *uio_MountTree_alloc(void);
|
static inline uio_MountTree *uio_MountTree_alloc(void);
|
||||||
static inline uio_MountTreeItem *uio_MountTreeItem_alloc(void);
|
static inline uio_MountTreeItem *uio_MountTreeItem_alloc(void);
|
||||||
static inline uio_MountInfo *uio_MountInfo_alloc(void);
|
static inline uio_MountInfo *uio_MountInfo_alloc(void);
|
||||||
static inline uio_PathComp *uio_PathComp_alloc(void);
|
|
||||||
|
|
||||||
static inline void uio_freeMountTree(uio_MountTree *mountTree);
|
static inline void uio_MountTree_free(uio_MountTree *mountTree);
|
||||||
static inline void uio_freeMountTreeItem(uio_MountTreeItem *mountTreeItem);
|
static inline void uio_MountTreeItem_free(uio_MountTreeItem *mountTreeItem);
|
||||||
static inline void uio_freeMountInfo(uio_MountInfo *mountInfo);
|
static inline void uio_MountInfo_free(uio_MountInfo *mountInfo);
|
||||||
static inline void uio_freePathComp(uio_PathComp *pathComp);
|
|
||||||
|
|
||||||
|
|
||||||
// make the root mount Tree
|
// make the root mount Tree
|
||||||
@@ -409,7 +400,7 @@ uio_mountTreeRemoveMountInfo(uio_Repository *repository,
|
|||||||
upTree = mountTree->upTree;
|
upTree = mountTree->upTree;
|
||||||
|
|
||||||
// Remove the tree itself.
|
// Remove the tree itself.
|
||||||
uio_deleteMountTree(mountTree);
|
uio_MountTree_delete(mountTree);
|
||||||
|
|
||||||
// The upTree itself could have become unnecessary now.
|
// The upTree itself could have become unnecessary now.
|
||||||
// This is the case when upTree now only has one subTree, and upTree
|
// This is the case when upTree now only has one subTree, and upTree
|
||||||
@@ -453,7 +444,7 @@ uio_mountTreeRemoveMountInfo(uio_Repository *repository,
|
|||||||
// Now delete the tree itself
|
// Now delete the tree itself
|
||||||
upTree->subTrees = NULL;
|
upTree->subTrees = NULL;
|
||||||
upTree->comps = NULL;
|
upTree->comps = NULL;
|
||||||
uio_deleteMountTree(upTree);
|
uio_MountTree_delete(upTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pre: mountInfo exists in mountTree->pLocs (and hence in pLocs for
|
// pre: mountInfo exists in mountTree->pLocs (and hence in pLocs for
|
||||||
@@ -484,28 +475,7 @@ uio_mountTreeRemoveMountInfoRec(uio_MountTree *mountTree,
|
|||||||
|
|
||||||
item = *itemPtr;
|
item = *itemPtr;
|
||||||
*itemPtr = item->next;
|
*itemPtr = item->next;
|
||||||
uio_deleteMountTreeItem(item);
|
uio_MountTreeItem_delete(item);
|
||||||
}
|
|
||||||
|
|
||||||
// Count the number of path components that 'comp' leads to.
|
|
||||||
static int
|
|
||||||
uio_countPathComps(const uio_PathComp *comp) {
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
for (; comp != NULL; comp = comp->next)
|
|
||||||
count++;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uio_PathComp *
|
|
||||||
uio_lastPathComp(uio_PathComp *comp) {
|
|
||||||
if (comp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while (comp->next != NULL)
|
|
||||||
comp = comp->next;
|
|
||||||
return comp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the number of pLocs in a tree that leads to.
|
// Count the number of pLocs in a tree that leads to.
|
||||||
@@ -520,30 +490,6 @@ uio_mountTreeCountPLocs(const uio_MountTree *tree) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a list of uio_PathComps from a path string
|
|
||||||
static uio_PathComp *
|
|
||||||
uio_makePathComps(const char *path, uio_PathComp *upComp) {
|
|
||||||
const char *start, *end;
|
|
||||||
char *str;
|
|
||||||
uio_PathComp *result;
|
|
||||||
uio_PathComp **compPtr; // Where to put the next PathComp
|
|
||||||
|
|
||||||
compPtr = &result;
|
|
||||||
getFirstPath0Component(path, &start, &end);
|
|
||||||
while (*start != '\0') {
|
|
||||||
str = uio_malloc(end - start + 1);
|
|
||||||
memcpy(str, start, end - start);
|
|
||||||
str[end - start] = '\0';
|
|
||||||
|
|
||||||
*compPtr = uio_PathComp_new(str, end - start, upComp);
|
|
||||||
upComp = *compPtr;
|
|
||||||
compPtr = &(*compPtr)->next;
|
|
||||||
getNextPath0Component(&start, &end);
|
|
||||||
}
|
|
||||||
*compPtr = NULL;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resTree may point to top
|
// resTree may point to top
|
||||||
// pPath may point to path
|
// pPath may point to path
|
||||||
void
|
void
|
||||||
@@ -691,20 +637,6 @@ uio_printPathToMountTree(FILE *outStream, const uio_MountTree *tree) {
|
|||||||
uio_printPathToComp(outStream, tree->lastComp);
|
uio_printPathToComp(outStream, tree->lastComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
uio_printPathComp(FILE *outStream, const uio_PathComp *comp) {
|
|
||||||
fprintf(outStream, "%s", comp->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
uio_printPathToComp(FILE *outStream, const uio_PathComp *comp) {
|
|
||||||
if (comp == NULL)
|
|
||||||
return;
|
|
||||||
uio_printPathToComp(outStream, comp->up);
|
|
||||||
fprintf(outStream, "/");
|
|
||||||
uio_printPathComp(outStream, comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
uio_printMountInfo(FILE *outStream, const uio_MountInfo *mountInfo) {
|
uio_printMountInfo(FILE *outStream, const uio_MountInfo *mountInfo) {
|
||||||
uio_FileSystemInfo *fsInfo;
|
uio_FileSystemInfo *fsInfo;
|
||||||
@@ -757,28 +689,28 @@ uio_MountTree_new(uio_MountTree *subTrees, uio_MountTreeItem *pLocs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uio_deleteMountTree(uio_MountTree *tree) {
|
uio_MountTree_delete(uio_MountTree *tree) {
|
||||||
uio_MountTree *subTree, *nextTree;
|
uio_MountTree *subTree, *nextTree;
|
||||||
uio_MountTreeItem *item, *nextItem;
|
uio_MountTreeItem *item, *nextItem;
|
||||||
|
|
||||||
subTree = tree->subTrees;
|
subTree = tree->subTrees;
|
||||||
while (subTree != NULL) {
|
while (subTree != NULL) {
|
||||||
nextTree = subTree->next;
|
nextTree = subTree->next;
|
||||||
uio_deleteMountTree(subTree);
|
uio_MountTree_delete(subTree);
|
||||||
subTree = nextTree;
|
subTree = nextTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
item = tree->pLocs;
|
item = tree->pLocs;
|
||||||
while (item != NULL) {
|
while (item != NULL) {
|
||||||
nextItem = item->next;
|
nextItem = item->next;
|
||||||
uio_deleteMountTreeItem(item);
|
uio_MountTreeItem_delete(item);
|
||||||
item = nextItem;
|
item = nextItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->comps != NULL)
|
if (tree->comps != NULL)
|
||||||
uio_deletePathComp(tree->comps);
|
uio_PathComp_delete(tree->comps);
|
||||||
|
|
||||||
uio_freeMountTree(tree);
|
uio_MountTree_free(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uio_MountTree *
|
static inline uio_MountTree *
|
||||||
@@ -791,7 +723,7 @@ uio_MountTree_alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
uio_freeMountTree(uio_MountTree *mountTree) {
|
uio_MountTree_free(uio_MountTree *mountTree) {
|
||||||
#ifdef uio_MEM_DEBUG
|
#ifdef uio_MEM_DEBUG
|
||||||
uio_MemDebug_debugFree(uio_MountTree, (void *) mountTree);
|
uio_MemDebug_debugFree(uio_MountTree, (void *) mountTree);
|
||||||
#endif
|
#endif
|
||||||
@@ -814,8 +746,8 @@ uio_MountTree_newItem(uio_MountInfo *mountInfo, int depth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
uio_deleteMountTreeItem(uio_MountTreeItem *item) {
|
uio_MountTreeItem_delete(uio_MountTreeItem *item) {
|
||||||
uio_freeMountTreeItem(item);
|
uio_MountTreeItem_free(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uio_MountTreeItem *
|
static inline uio_MountTreeItem *
|
||||||
@@ -828,7 +760,7 @@ uio_MountTreeItem_alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
uio_freeMountTreeItem(uio_MountTreeItem *mountTreeItem) {
|
uio_MountTreeItem_free(uio_MountTreeItem *mountTreeItem) {
|
||||||
#ifdef uio_MEM_DEBUG
|
#ifdef uio_MEM_DEBUG
|
||||||
uio_MemDebug_debugFree(uio_MountTreeItem, (void *) mountTreeItem);
|
uio_MemDebug_debugFree(uio_MountTreeItem, (void *) mountTreeItem);
|
||||||
#endif
|
#endif
|
||||||
@@ -856,10 +788,10 @@ uio_MountInfo_new(uio_FileSystemID fsID, uio_MountTree *mountTree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uio_deleteMountInfo(uio_MountInfo *mountInfo) {
|
uio_MountInfo_delete(uio_MountInfo *mountInfo) {
|
||||||
uio_free(mountInfo->dirName);
|
uio_free(mountInfo->dirName);
|
||||||
uio_PDirHandle_unref(mountInfo->pDirHandle);
|
uio_PDirHandle_unref(mountInfo->pDirHandle);
|
||||||
uio_freeMountInfo(mountInfo);
|
uio_MountInfo_free(mountInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uio_MountInfo *
|
static inline uio_MountInfo *
|
||||||
@@ -872,7 +804,7 @@ uio_MountInfo_alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
uio_freeMountInfo(uio_MountInfo *mountInfo) {
|
uio_MountInfo_free(uio_MountInfo *mountInfo) {
|
||||||
#ifdef uio_MEM_DEBUG
|
#ifdef uio_MEM_DEBUG
|
||||||
uio_MemDebug_debugFree(uio_MountInfo, (void *) mountInfo);
|
uio_MemDebug_debugFree(uio_MountInfo, (void *) mountInfo);
|
||||||
#endif
|
#endif
|
||||||
@@ -880,49 +812,3 @@ uio_freeMountInfo(uio_MountInfo *mountInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// *** uio_PathComp *** //
|
|
||||||
|
|
||||||
// 'name' should be a null terminated string. It is stored in the PathComp,
|
|
||||||
// no copy is made.
|
|
||||||
// 'namelen' should be the length of 'name'
|
|
||||||
static inline uio_PathComp *
|
|
||||||
uio_PathComp_new(char *name, size_t nameLen, uio_PathComp *upComp) {
|
|
||||||
uio_PathComp *result;
|
|
||||||
|
|
||||||
result = uio_PathComp_alloc();
|
|
||||||
result->name = name;
|
|
||||||
result->nameLen = nameLen;
|
|
||||||
result->up = upComp;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
uio_deletePathComp(uio_PathComp *pathComp) {
|
|
||||||
uio_PathComp *next;
|
|
||||||
|
|
||||||
while (pathComp != NULL) {
|
|
||||||
next = pathComp->next;
|
|
||||||
uio_free(pathComp->name);
|
|
||||||
uio_freePathComp(pathComp);
|
|
||||||
pathComp = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uio_PathComp *
|
|
||||||
uio_PathComp_alloc(void) {
|
|
||||||
uio_PathComp *result = uio_malloc(sizeof (uio_PathComp));
|
|
||||||
#ifdef uio_MEM_DEBUG
|
|
||||||
uio_MemDebug_debugAlloc(uio_PathComp, (void *) result);
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
uio_freePathComp(uio_PathComp *pathComp) {
|
|
||||||
#ifdef uio_MEM_DEBUG
|
|
||||||
uio_MemDebug_debugFree(uio_PathComp, (void *) pathComp);
|
|
||||||
#endif
|
|
||||||
uio_free(pathComp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,12 +33,12 @@ void uio_printMounts(FILE *outStream, const uio_Repository *repository);
|
|||||||
|
|
||||||
typedef struct uio_MountTreeItem uio_MountTreeItem;
|
typedef struct uio_MountTreeItem uio_MountTreeItem;
|
||||||
typedef struct uio_MountTree uio_MountTree;
|
typedef struct uio_MountTree uio_MountTree;
|
||||||
typedef struct uio_PathComp uio_PathComp;
|
|
||||||
typedef struct uio_MountInfo uio_MountInfo;
|
typedef struct uio_MountInfo uio_MountInfo;
|
||||||
|
|
||||||
#include "physical.h"
|
#include "physical.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "uioport.h"
|
#include "uioport.h"
|
||||||
|
#include "paths.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -69,19 +69,6 @@ struct uio_MountTreeItem {
|
|||||||
// The next MountTreeItem in a MountTree
|
// The next MountTreeItem in a MountTree
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uio_PathComp {
|
|
||||||
char *name;
|
|
||||||
// The name of this path component, 0-terminated
|
|
||||||
size_t nameLen;
|
|
||||||
// The length of the 'name' field, for fast lookups.
|
|
||||||
struct uio_PathComp *next;
|
|
||||||
// The next path component leading to a MountTree
|
|
||||||
// If this is NULL, then this was the last component
|
|
||||||
// until the MountTree that
|
|
||||||
struct uio_PathComp *up;
|
|
||||||
// Links to the directory
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uio_MountTree {
|
struct uio_MountTree {
|
||||||
struct uio_MountTree *subTrees;
|
struct uio_MountTree *subTrees;
|
||||||
// Trees for subdirs in this MountTree
|
// Trees for subdirs in this MountTree
|
||||||
@@ -183,7 +170,7 @@ struct uio_MountInfo {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
uio_MountTree *uio_makeRootMountTree(void);
|
uio_MountTree *uio_makeRootMountTree(void);
|
||||||
void uio_deleteMountTree(uio_MountTree *tree);
|
void uio_MountTree_delete(uio_MountTree *tree);
|
||||||
uio_MountTree *uio_mountTreeAddMountInfo(uio_Repository *repository,
|
uio_MountTree *uio_mountTreeAddMountInfo(uio_Repository *repository,
|
||||||
uio_MountTree *mountTree, uio_MountInfo *mountInfo, const char *path,
|
uio_MountTree *mountTree, uio_MountInfo *mountInfo, const char *path,
|
||||||
uio_MountLocation location, const uio_MountInfo *relative);
|
uio_MountLocation location, const uio_MountInfo *relative);
|
||||||
@@ -198,13 +185,12 @@ uio_MountInfo *uio_MountInfo_new(uio_FileSystemID fsID,
|
|||||||
uio_MountTree *mountTree, uio_PDirHandle *pDirHandle,
|
uio_MountTree *mountTree, uio_PDirHandle *pDirHandle,
|
||||||
char *dirName, uio_AutoMount **autoMount,
|
char *dirName, uio_AutoMount **autoMount,
|
||||||
uio_MountHandle *mountHandle, int flags);
|
uio_MountHandle *mountHandle, int flags);
|
||||||
void uio_deleteMountInfo(uio_MountInfo *mountInfo);
|
void uio_MountInfo_delete(uio_MountInfo *mountInfo);
|
||||||
void uio_printMountTree(FILE *outStream, const uio_MountTree *tree, int indent);
|
void uio_printMountTree(FILE *outStream, const uio_MountTree *tree,
|
||||||
|
int indent);
|
||||||
void uio_printMountTreeItem(FILE *outStream, const uio_MountTreeItem *item);
|
void uio_printMountTreeItem(FILE *outStream, const uio_MountTreeItem *item);
|
||||||
void uio_printMountTreeItems(FILE *outStream, const uio_MountTreeItem *item);
|
void uio_printMountTreeItems(FILE *outStream, const uio_MountTreeItem *item);
|
||||||
void uio_printPathToMountTree(FILE *outStream, const uio_MountTree *tree);
|
void uio_printPathToMountTree(FILE *outStream, const uio_MountTree *tree);
|
||||||
void uio_printPathComp(FILE *outStream, const uio_PathComp *comp);
|
|
||||||
void uio_printPathToComp(FILE *outStream, const uio_PathComp *comp);
|
|
||||||
void uio_printMountInfo(FILE *outStream, const uio_MountInfo *mountInfo);
|
void uio_printMountInfo(FILE *outStream, const uio_MountInfo *mountInfo);
|
||||||
|
|
||||||
static inline uio_bool
|
static inline uio_bool
|
||||||
|
|||||||
@@ -18,14 +18,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "paths.h"
|
#include "paths.h"
|
||||||
#include "uioport.h"
|
#include "uioport.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
|
static inline uio_PathComp *uio_PathComp_alloc(void);
|
||||||
|
static inline void uio_PathComp_free(uio_PathComp *pathComp);
|
||||||
|
|
||||||
// gets the first dir component of a path
|
// gets the first dir component of a path
|
||||||
// sets '*start' to the start of the first component
|
// sets '*start' to the start of the first component
|
||||||
// sets '*end' to the end of the first component
|
// sets '*end' to the end of the first component
|
||||||
@@ -236,4 +240,357 @@ validPathName(const char *path, size_t len) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns 0 if the path is not a valid UNC path.
|
||||||
|
// Does not skip trailing slashes.
|
||||||
|
size_t
|
||||||
|
uio_skipUNCServerShare(const char *inPath) {
|
||||||
|
const char *path = inPath;
|
||||||
|
|
||||||
|
// Skip the initial two backslashes.
|
||||||
|
if (path[0] != '\\' || path[1] != '\\')
|
||||||
|
return (size_t) 0;
|
||||||
|
path += 2;
|
||||||
|
|
||||||
|
// Skip the server part.
|
||||||
|
while (*path != '\\' && *path != '/') {
|
||||||
|
if (*path == '\0')
|
||||||
|
return (size_t) 0;
|
||||||
|
path++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the seperator.
|
||||||
|
path++;
|
||||||
|
|
||||||
|
// Skip the share part.
|
||||||
|
while (*path != '\0' && *path != '\\' && *path != '/')
|
||||||
|
path++;
|
||||||
|
|
||||||
|
return (size_t) (path - inPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the server and share part of a Windows "Universal Naming Convention"
|
||||||
|
* path (a path of the form '\\server\share\path\file').
|
||||||
|
* The path must contain at least a server and share path to be valid.
|
||||||
|
* The initial two slashes must be backslashes, the other slashes may each
|
||||||
|
* be either a forward slash or a backslash.
|
||||||
|
*
|
||||||
|
* @param[in] inPath The path to parse.
|
||||||
|
* @param[out] outPath Will contain a newly allocated string (to be
|
||||||
|
* freed using uio_free(), containing the server and share part
|
||||||
|
* of inPath, separated by a backslash, or NULL if 'inPath' was
|
||||||
|
* not a valid UNC path.
|
||||||
|
* @param[out] outLen If not NULL on entry, it will contain the string
|
||||||
|
* length of '*outPath', or 0 if 'inPath' was not a valid UNC path.
|
||||||
|
*
|
||||||
|
* @returns The number of characters to add to 'inPath' to get to the first
|
||||||
|
* path component past the server and share part, or 0 if 'inPath'
|
||||||
|
* was not a valid UNC path.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
uio_getUNCServerShare(const char *inPath, char **outPath, size_t *outLen) {
|
||||||
|
const char *ptr;
|
||||||
|
const char *server;
|
||||||
|
const char *serverEnd;
|
||||||
|
const char *share;
|
||||||
|
const char *shareEnd;
|
||||||
|
char *name;
|
||||||
|
char *nameEnd;
|
||||||
|
size_t nameLen;
|
||||||
|
|
||||||
|
ptr = inPath;
|
||||||
|
|
||||||
|
if (ptr[0] != '\\' || ptr[1] != '\\')
|
||||||
|
goto noMatch;
|
||||||
|
|
||||||
|
// Parse the server part.
|
||||||
|
server = ptr + 2;
|
||||||
|
serverEnd = server;
|
||||||
|
for (;;) {
|
||||||
|
if (*serverEnd == '\0')
|
||||||
|
goto noMatch;
|
||||||
|
if (isPathDelimiter(*serverEnd))
|
||||||
|
break;
|
||||||
|
serverEnd++;
|
||||||
|
}
|
||||||
|
if (serverEnd == server)
|
||||||
|
goto noMatch;
|
||||||
|
|
||||||
|
// Parse the share part.
|
||||||
|
share = serverEnd + 1;
|
||||||
|
shareEnd = share;
|
||||||
|
while (*shareEnd != '\0') {
|
||||||
|
if (isPathDelimiter(*shareEnd))
|
||||||
|
break;
|
||||||
|
serverEnd++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip any trailing path delimiters.
|
||||||
|
ptr = shareEnd;
|
||||||
|
while (isPathDelimiter(*ptr))
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
// Allocate a new string and fill it.
|
||||||
|
nameLen = (serverEnd - server) + (shareEnd - share) + 3;
|
||||||
|
name = uio_malloc(nameLen + 1);
|
||||||
|
nameEnd = name;
|
||||||
|
*(nameEnd++) = '\\';
|
||||||
|
*(nameEnd++) = '\\';
|
||||||
|
memcpy(nameEnd, server, serverEnd - server);
|
||||||
|
*(nameEnd++) = '\\';
|
||||||
|
memcpy(nameEnd, share, shareEnd - share);
|
||||||
|
*nameEnd = '\0';
|
||||||
|
|
||||||
|
*outPath = name;
|
||||||
|
if (outLen != NULL)
|
||||||
|
*outLen = nameLen;
|
||||||
|
return (size_t) (ptr - inPath);
|
||||||
|
|
||||||
|
noMatch:
|
||||||
|
*outPath = NULL;
|
||||||
|
if (outLen != NULL)
|
||||||
|
*outLen = 0;
|
||||||
|
return (size_t) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decomposes a path into its components.
|
||||||
|
// If isAbsolute is not NULL, *isAbsolute will be set to true
|
||||||
|
// iff the path is absolute.
|
||||||
|
// As POSIX considers multiple consecutive slashes to be equivalent to
|
||||||
|
// a single slash, so will uio (but not in the "\\MACHINE\share" part
|
||||||
|
// of a Windows UNC path).
|
||||||
|
int
|
||||||
|
decomposePath(const char *path, uio_PathComp **pathComp,
|
||||||
|
uio_bool *isAbsolute) {
|
||||||
|
uio_PathComp *result;
|
||||||
|
uio_PathComp *last;
|
||||||
|
uio_PathComp **endResult = &result;
|
||||||
|
uio_bool absolute = false;
|
||||||
|
char *name;
|
||||||
|
#ifdef WIN32
|
||||||
|
size_t nameLen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (path[0] == '\0') {
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = NULL;
|
||||||
|
#ifdef WIN32
|
||||||
|
path += uio_getUNCServerShare(path, &name, &nameLen);
|
||||||
|
if (name != NULL) {
|
||||||
|
// UNC path
|
||||||
|
*endResult = uio_PathComp_new(name, nameLen, last);
|
||||||
|
last = *endResult;
|
||||||
|
endResult = &last->next;
|
||||||
|
|
||||||
|
absolute = true;
|
||||||
|
} else if (isDriveLetter(path[0]) && path[1] == ':') {
|
||||||
|
// DOS/Windows drive letter.
|
||||||
|
if (path[2] != '\0' && !isPathDelimiter(path[2])) {
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
name = uio_memdup0(path, 2);
|
||||||
|
*endResult = uio_PathComp_new(name, 2, last);
|
||||||
|
last = *endResult;
|
||||||
|
endResult = &last->next;
|
||||||
|
absolute = true;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (isPathDelimiter(*path)) {
|
||||||
|
absolute = true;
|
||||||
|
do {
|
||||||
|
path++;
|
||||||
|
} while (isPathDelimiter(*path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*path != '\0') {
|
||||||
|
const char *start = path;
|
||||||
|
while (*path != '\0' && !isPathDelimiter(*path))
|
||||||
|
path++;
|
||||||
|
|
||||||
|
name = uio_memdup0(path, path - start);
|
||||||
|
*endResult = uio_PathComp_new(name, path - start, last);
|
||||||
|
last = *endResult;
|
||||||
|
endResult = &last->next;
|
||||||
|
|
||||||
|
while (isPathDelimiter(*path))
|
||||||
|
path++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*endResult = NULL;
|
||||||
|
*pathComp = result;
|
||||||
|
if (isAbsolute != NULL)
|
||||||
|
*isAbsolute = absolute;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre: pathComp forms a valid path for the platform.
|
||||||
|
void
|
||||||
|
composePath(const uio_PathComp *pathComp, uio_bool absolute,
|
||||||
|
char **path, size_t *pathLen) {
|
||||||
|
size_t len;
|
||||||
|
const uio_PathComp *ptr;
|
||||||
|
char *result;
|
||||||
|
char *pathPtr;
|
||||||
|
|
||||||
|
assert(pathComp != NULL);
|
||||||
|
|
||||||
|
// First determine how much space is required.
|
||||||
|
len = 0;
|
||||||
|
if (absolute)
|
||||||
|
len++;
|
||||||
|
ptr = pathComp;
|
||||||
|
while (ptr != NULL) {
|
||||||
|
len += ptr->nameLen;
|
||||||
|
ptr = ptr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate the required space.
|
||||||
|
result = (char *) uio_malloc(len + 1);
|
||||||
|
|
||||||
|
// Fill the path.
|
||||||
|
pathPtr = result;
|
||||||
|
ptr = pathComp;
|
||||||
|
if (absolute) {
|
||||||
|
#ifdef WIN32
|
||||||
|
if (ptr->name[0] == '\\') {
|
||||||
|
// UNC path
|
||||||
|
assert(ptr->name[1] == '\\');
|
||||||
|
// Nothing to do.
|
||||||
|
} else if (ptr->nameLen == 2 && ptr->name[1] == ':'
|
||||||
|
&& isDriveLetter(ptr->name[0])) {
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
*(pathPtr++) = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
memcpy(pathPtr, ptr->name, ptr->nameLen);
|
||||||
|
pathPtr += ptr->nameLen;
|
||||||
|
|
||||||
|
ptr = ptr->next;
|
||||||
|
if (ptr == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*(pathPtr++) = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
*path = result;
|
||||||
|
*pathLen = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *** uio_PathComp *** //
|
||||||
|
|
||||||
|
static inline uio_PathComp *
|
||||||
|
uio_PathComp_alloc(void) {
|
||||||
|
uio_PathComp *result = uio_malloc(sizeof (uio_PathComp));
|
||||||
|
#ifdef uio_MEM_DEBUG
|
||||||
|
uio_MemDebug_debugAlloc(uio_PathComp, (void *) result);
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
uio_PathComp_free(uio_PathComp *pathComp) {
|
||||||
|
#ifdef uio_MEM_DEBUG
|
||||||
|
uio_MemDebug_debugFree(uio_PathComp, (void *) pathComp);
|
||||||
|
#endif
|
||||||
|
uio_free(pathComp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'name' should be a null terminated string. It is stored in the PathComp,
|
||||||
|
// no copy is made.
|
||||||
|
// 'namelen' should be the length of 'name'
|
||||||
|
uio_PathComp *
|
||||||
|
uio_PathComp_new(char *name, size_t nameLen, uio_PathComp *upComp) {
|
||||||
|
uio_PathComp *result;
|
||||||
|
|
||||||
|
result = uio_PathComp_alloc();
|
||||||
|
result->name = name;
|
||||||
|
result->nameLen = nameLen;
|
||||||
|
result->up = upComp;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uio_PathComp_delete(uio_PathComp *pathComp) {
|
||||||
|
uio_PathComp *next;
|
||||||
|
|
||||||
|
while (pathComp != NULL) {
|
||||||
|
next = pathComp->next;
|
||||||
|
uio_free(pathComp->name);
|
||||||
|
uio_PathComp_free(pathComp);
|
||||||
|
pathComp = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of path components that 'comp' leads to.
|
||||||
|
int
|
||||||
|
uio_countPathComps(const uio_PathComp *comp) {
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (; comp != NULL; comp = comp->next)
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uio_PathComp *
|
||||||
|
uio_lastPathComp(uio_PathComp *comp) {
|
||||||
|
if (comp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (comp->next != NULL)
|
||||||
|
comp = comp->next;
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a list of uio_PathComps from a path string
|
||||||
|
uio_PathComp *
|
||||||
|
uio_makePathComps(const char *path, uio_PathComp *upComp) {
|
||||||
|
const char *start, *end;
|
||||||
|
char *str;
|
||||||
|
uio_PathComp *result;
|
||||||
|
uio_PathComp **compPtr; // Where to put the next PathComp
|
||||||
|
|
||||||
|
compPtr = &result;
|
||||||
|
getFirstPath0Component(path, &start, &end);
|
||||||
|
while (*start != '\0') {
|
||||||
|
str = uio_malloc(end - start + 1);
|
||||||
|
memcpy(str, start, end - start);
|
||||||
|
str[end - start] = '\0';
|
||||||
|
|
||||||
|
*compPtr = uio_PathComp_new(str, end - start, upComp);
|
||||||
|
upComp = *compPtr;
|
||||||
|
compPtr = &(*compPtr)->next;
|
||||||
|
getNextPath0Component(&start, &end);
|
||||||
|
}
|
||||||
|
*compPtr = NULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uio_printPathComp(FILE *outStream, const uio_PathComp *comp) {
|
||||||
|
fprintf(outStream, "%s", comp->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uio_printPathToComp(FILE *outStream, const uio_PathComp *comp) {
|
||||||
|
if (comp == NULL)
|
||||||
|
return;
|
||||||
|
uio_printPathToComp(outStream, comp->up);
|
||||||
|
fprintf(outStream, "/");
|
||||||
|
uio_printPathComp(outStream, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,26 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PATHS_H
|
#ifndef _PATHS_H
|
||||||
#define PATHS_H
|
#define _PATHS_H
|
||||||
|
|
||||||
|
typedef struct uio_PathComp uio_PathComp;
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "uioport.h"
|
#include "uioport.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct uio_PathComp {
|
||||||
|
char *name;
|
||||||
|
// The name of this path component, 0-terminated
|
||||||
|
size_t nameLen;
|
||||||
|
// The length of the 'name' field, for fast lookups.
|
||||||
|
struct uio_PathComp *next;
|
||||||
|
// Next component in the path.
|
||||||
|
struct uio_PathComp *up;
|
||||||
|
// Previous component in the path.
|
||||||
|
};
|
||||||
|
|
||||||
void getFirstPathComponent(const char *dir, const char *dirEnd,
|
void getFirstPathComponent(const char *dir, const char *dirEnd,
|
||||||
const char **startComp, const char **endComp);
|
const char **startComp, const char **endComp);
|
||||||
void getFirstPath0Component(const char *dir, const char **startComp,
|
void getFirstPath0Component(const char *dir, const char **startComp,
|
||||||
@@ -42,6 +57,40 @@ char *joinPaths(const char *first, const char *second);
|
|||||||
char *joinPathsAbsolute(const char *first, const char *second);
|
char *joinPathsAbsolute(const char *first, const char *second);
|
||||||
|
|
||||||
uio_bool validPathName(const char *path, size_t len);
|
uio_bool validPathName(const char *path, size_t len);
|
||||||
|
size_t uio_skipUNCServerShare(const char *inPath);
|
||||||
|
size_t uio_getUNCServerShare(const char *inPath, char **outPath,
|
||||||
|
size_t *outLen);
|
||||||
|
|
||||||
#endif /* PATHS_H */
|
#ifdef WIN32
|
||||||
|
static inline int
|
||||||
|
isDriveLetter(int c)
|
||||||
|
{
|
||||||
|
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
isPathDelimiter(int c)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
return c == '/' || c == '\\';
|
||||||
|
#else
|
||||||
|
return c == '/';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int decomposePath(const char *path, uio_PathComp **pathComp,
|
||||||
|
uio_bool *isAbsolute);
|
||||||
|
void composePath(const uio_PathComp *pathComp, uio_bool absolute,
|
||||||
|
char **path, size_t *pathLen);
|
||||||
|
uio_PathComp *uio_PathComp_new(char *name, size_t nameLen,
|
||||||
|
uio_PathComp *upComp);
|
||||||
|
void uio_PathComp_delete(uio_PathComp *pathComp);
|
||||||
|
int uio_countPathComps(const uio_PathComp *comp);
|
||||||
|
uio_PathComp *uio_lastPathComp(uio_PathComp *comp);
|
||||||
|
uio_PathComp *uio_makePathComps(const char *path, uio_PathComp *upComp);
|
||||||
|
void uio_printPathComp(FILE *outStream, const uio_PathComp *comp);
|
||||||
|
void uio_printPathToComp(FILE *outStream, const uio_PathComp *comp);
|
||||||
|
|
||||||
|
#endif /* _PATHS_H */
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#ifdef __svr4__
|
#ifdef __svr4__
|
||||||
# define _POSIX_PTHREAD_SEMANTICS
|
# define _POSIX_PTHREAD_SEMANTICS
|
||||||
// For the POSIX variant of r_readdir()
|
// For the POSIX variant of readdir_r()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "./stdio.h"
|
#include "./stdio.h"
|
||||||
@@ -348,13 +348,23 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (pDirHandle->extra->extra->upDir == NULL) {
|
if (pDirHandle->extra->extra->upDir == NULL) {
|
||||||
// Top dir. Contains only drive letters.
|
// Top dir. Contains only drive letters and UNC \\server\share
|
||||||
if (!isDriveLetter(name[0]) || name[1] != ':' || name[2] != '\0')
|
// parts.
|
||||||
return NULL;
|
if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') {
|
||||||
driveName[0] = tolower(name[0]);
|
driveName[0] = tolower(name[0]);
|
||||||
driveName[1] = ':';
|
driveName[1] = ':';
|
||||||
driveName[2] = '\0';
|
driveName[2] = '\0';
|
||||||
name = driveName;
|
name = driveName;
|
||||||
|
} else {
|
||||||
|
size_t uncLen;
|
||||||
|
|
||||||
|
uncLen = uio_skipUNCServerShare(name);
|
||||||
|
if (name[uncLen] != '\0') {
|
||||||
|
// 'name' contains neither a drive letter, nor the
|
||||||
|
// first part of a UNC path.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -363,8 +373,9 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (name == driveName) {
|
if (pDirHandle->extra->extra->upDir == NULL) {
|
||||||
// Need to create a 'directory' for the drive letter.
|
// Need to create a 'directory' for the drive letter or UNC
|
||||||
|
// "\\server\share" part.
|
||||||
// It's no problem if we happen to create a dir for a non-existing
|
// It's no problem if we happen to create a dir for a non-existing
|
||||||
// drive. It should just produce an empty dir.
|
// drive. It should just produce an empty dir.
|
||||||
uio_GPDir *gPDir;
|
uio_GPDir *gPDir;
|
||||||
@@ -703,7 +714,7 @@ stdio_getPath(uio_GPDir *gPDir) {
|
|||||||
|
|
||||||
if (gPDir->extra->upDir == NULL) {
|
if (gPDir->extra->upDir == NULL) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// Drive letter still needs to follow follow.
|
// Drive letter still needs to follow.
|
||||||
gPDir->extra->cachedPath = uio_malloc(1);
|
gPDir->extra->cachedPath = uio_malloc(1);
|
||||||
gPDir->extra->cachedPath[0] = '\0';
|
gPDir->extra->cachedPath[0] = '\0';
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -107,11 +107,3 @@ void stdio_EntriesIterator_delete(stdio_EntriesIterator *iterator);
|
|||||||
uio_PDirEntryHandle *stdio_getPDirEntryHandle(
|
uio_PDirEntryHandle *stdio_getPDirEntryHandle(
|
||||||
const uio_PDirHandle *pDirHandle, const char *name);
|
const uio_PDirHandle *pDirHandle, const char *name);
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
static inline int isDriveLetter(int c)
|
|
||||||
{
|
|
||||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,18 @@
|
|||||||
|
|
||||||
#include "uioutils.h"
|
#include "uioutils.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "paths.h"
|
||||||
#include "uioport.h"
|
#include "uioport.h"
|
||||||
|
|
||||||
// concattenate two strings into a newly allocated buffer.
|
/**
|
||||||
// It's up to the caller to free it.
|
* Concatenate two strings into a newly allocated buffer.
|
||||||
|
*
|
||||||
|
* @param[in] first The first (left) string, '\0' terminated.
|
||||||
|
* @param[in] second The second (right) string, '\0' terminated.
|
||||||
|
*
|
||||||
|
* @returns A newly allocated string consisting of the concatenation of
|
||||||
|
* 'first' and 'second', to be freed using uio_free().
|
||||||
|
*/
|
||||||
char *
|
char *
|
||||||
strcata(const char *first, const char *second) {
|
strcata(const char *first, const char *second) {
|
||||||
char *result, *resPtr;
|
char *result, *resPtr;
|
||||||
@@ -144,7 +152,7 @@ dosToUnixTime(uio_uint16 date, uio_uint16 tm) {
|
|||||||
static const int daysUntilMonth[] = {
|
static const int daysUntilMonth[] = {
|
||||||
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
|
||||||
334, 334, 334, 334 };
|
334, 334, 334, 334 };
|
||||||
// Last 4 entries are there so that there's no
|
// The last 4 entries are there so that there's no
|
||||||
// invalid memory access if the date is invalid.
|
// invalid memory access if the date is invalid.
|
||||||
|
|
||||||
year = date >> 9;
|
year = date >> 9;
|
||||||
@@ -181,10 +189,30 @@ char *
|
|||||||
dosToUnixPath(const char *path) {
|
dosToUnixPath(const char *path) {
|
||||||
const char *srcPtr;
|
const char *srcPtr;
|
||||||
char *result, *dstPtr;
|
char *result, *dstPtr;
|
||||||
|
size_t skip;
|
||||||
|
|
||||||
result = uio_malloc(strlen(path) + 1);
|
result = uio_malloc(strlen(path) + 1);
|
||||||
srcPtr = path;
|
srcPtr = path;
|
||||||
dstPtr = result;
|
dstPtr = result;
|
||||||
|
|
||||||
|
// A UNC path will look like this: "\\server\share/..."; the first two
|
||||||
|
// characters will be backslashes, and the separator between the server
|
||||||
|
// and the share too. The rest will be slashes.
|
||||||
|
// The goal is that at every forward slash, the path should be
|
||||||
|
// stat()'able.
|
||||||
|
skip = uio_skipUNCServerShare(srcPtr);
|
||||||
|
if (skip != 0) {
|
||||||
|
char *slash;
|
||||||
|
memcpy(dstPtr, srcPtr, skip);
|
||||||
|
|
||||||
|
slash = memchr(srcPtr + 2, '/', skip - 2);
|
||||||
|
if (slash != NULL)
|
||||||
|
*slash = '\\';
|
||||||
|
|
||||||
|
srcPtr += skip;
|
||||||
|
dstPtr += skip;
|
||||||
|
}
|
||||||
|
|
||||||
while (*srcPtr != '\0') {
|
while (*srcPtr != '\0') {
|
||||||
if (*srcPtr == '\\') {
|
if (*srcPtr == '\\') {
|
||||||
*dstPtr = '/';
|
*dstPtr = '/';
|
||||||
|
|||||||
@@ -193,7 +193,8 @@ count_marines (STARSHIPPTR StarShipPtr, BOOLEAN FindSpot)
|
|||||||
|
|
||||||
LockElement (hElement, &ElementPtr);
|
LockElement (hElement, &ElementPtr);
|
||||||
hNextElement = GetPredElement (ElementPtr);
|
hNextElement = GetPredElement (ElementPtr);
|
||||||
if (ElementPtr->current.image.farray == StarShipPtr->RaceDescPtr->ship_data.special
|
if (ElementPtr->current.image.farray ==
|
||||||
|
StarShipPtr->RaceDescPtr->ship_data.special
|
||||||
&& ElementPtr->life_span
|
&& ElementPtr->life_span
|
||||||
&& !(ElementPtr->state_flags & (FINITE_LIFE | DISAPPEARING)))
|
&& !(ElementPtr->state_flags & (FINITE_LIFE | DISAPPEARING)))
|
||||||
{
|
{
|
||||||
@@ -222,7 +223,8 @@ count_marines (STARSHIPPTR StarShipPtr, BOOLEAN FindSpot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
orz_intelligence (PELEMENT ShipPtr, PEVALUATE_DESC ObjectsOfConcern, COUNT ConcernCounter)
|
orz_intelligence (PELEMENT ShipPtr, PEVALUATE_DESC ObjectsOfConcern,
|
||||||
|
COUNT ConcernCounter)
|
||||||
{
|
{
|
||||||
ELEMENTPTR TurretPtr;
|
ELEMENTPTR TurretPtr;
|
||||||
STARSHIPPTR StarShipPtr;
|
STARSHIPPTR StarShipPtr;
|
||||||
@@ -328,8 +330,7 @@ ion_preprocess (PELEMENT ElementPtr)
|
|||||||
COLOR Color;
|
COLOR Color;
|
||||||
|
|
||||||
Color = COLOR_256 (GetPrimColor (&(GLOBAL (DisplayArray))[
|
Color = COLOR_256 (GetPrimColor (&(GLOBAL (DisplayArray))[
|
||||||
ElementPtr->PrimIndex
|
ElementPtr->PrimIndex]));
|
||||||
]));
|
|
||||||
if (Color != 0x2D)
|
if (Color != 0x2D)
|
||||||
{
|
{
|
||||||
ElementPtr->life_span = ElementPtr->thrust_wait;
|
ElementPtr->life_span = ElementPtr->thrust_wait;
|
||||||
@@ -344,8 +345,7 @@ ion_preprocess (PELEMENT ElementPtr)
|
|||||||
else /* color is between 0x7a and 0x7f */
|
else /* color is between 0x7a and 0x7f */
|
||||||
color_index = (COUNT)(Color - 0x7a) + (NUM_TAB_COLORS >> 1);
|
color_index = (COUNT)(Color - 0x7a) + (NUM_TAB_COLORS >> 1);
|
||||||
SetPrimColor (&(GLOBAL (DisplayArray))[
|
SetPrimColor (&(GLOBAL (DisplayArray))[
|
||||||
ElementPtr->PrimIndex
|
ElementPtr->PrimIndex], color_tab[color_index]);
|
||||||
], color_tab[color_index]);
|
|
||||||
|
|
||||||
ElementPtr->state_flags &= ~DISAPPEARING;
|
ElementPtr->state_flags &= ~DISAPPEARING;
|
||||||
ElementPtr->state_flags |= CHANGING;
|
ElementPtr->state_flags |= CHANGING;
|
||||||
@@ -454,15 +454,13 @@ LeftShip:
|
|||||||
{
|
{
|
||||||
ElementPtr->state_flags &= ~NONSOLID;
|
ElementPtr->state_flags &= ~NONSOLID;
|
||||||
ElementPtr->state_flags |= CHANGING | CREW_OBJECT;
|
ElementPtr->state_flags |= CHANGING | CREW_OBJECT;
|
||||||
SetPrimType (&(GLOBAL (DisplayArray))[
|
SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex],
|
||||||
ElementPtr->PrimIndex
|
STAMP_PRIM);
|
||||||
], STAMP_PRIM);
|
|
||||||
|
|
||||||
ElementPtr->current.image.frame =
|
ElementPtr->current.image.frame =
|
||||||
ElementPtr->next.image.frame =
|
ElementPtr->next.image.frame =
|
||||||
SetAbsFrameIndex (
|
SetAbsFrameIndex (
|
||||||
StarShipPtr->RaceDescPtr->ship_data.special[0], 21
|
StarShipPtr->RaceDescPtr->ship_data.special[0], 21);
|
||||||
);
|
|
||||||
ElementPtr->thrust_wait = 0;
|
ElementPtr->thrust_wait = 0;
|
||||||
ElementPtr->turn_wait =
|
ElementPtr->turn_wait =
|
||||||
MAKE_BYTE (0, NORMALIZE_FACING ((BYTE)TFB_Random ()));
|
MAKE_BYTE (0, NORMALIZE_FACING ((BYTE)TFB_Random ()));
|
||||||
@@ -523,9 +521,8 @@ PELEMENT ElementPtr;
|
|||||||
pfacing = ANGLE_TO_FACING (ARCTAN (delta_x, delta_y));
|
pfacing = ANGLE_TO_FACING (ARCTAN (delta_x, delta_y));
|
||||||
delta_facing = NORMALIZE_FACING (
|
delta_facing = NORMALIZE_FACING (
|
||||||
pfacing - ANGLE_TO_FACING (
|
pfacing - ANGLE_TO_FACING (
|
||||||
GetVelocityTravelAngle (&ElementPtr->velocity)
|
GetVelocityTravelAngle (&ElementPtr->velocity))
|
||||||
) + ANGLE_TO_FACING (OCTANT)
|
+ ANGLE_TO_FACING (OCTANT));
|
||||||
);
|
|
||||||
if (delta_facing <= ANGLE_TO_FACING (QUADRANT))
|
if (delta_facing <= ANGLE_TO_FACING (QUADRANT))
|
||||||
{
|
{
|
||||||
hTarget = hObject;
|
hTarget = hObject;
|
||||||
@@ -589,18 +586,17 @@ PELEMENT ElementPtr;
|
|||||||
(ElementPtr->state_flags & (GOOD_GUY | BAD_GUY))
|
(ElementPtr->state_flags & (GOOD_GUY | BAD_GUY))
|
||||||
&& (ElementPtr->state_flags & IGNORE_SIMILAR))
|
&& (ElementPtr->state_flags & IGNORE_SIMILAR))
|
||||||
{
|
{
|
||||||
ElementPtr->next.image.frame =
|
ElementPtr->next.image.frame = SetAbsFrameIndex (
|
||||||
SetAbsFrameIndex (
|
StarShipPtr->RaceDescPtr->ship_data.special[0],
|
||||||
StarShipPtr->RaceDescPtr->ship_data.special[0], 21
|
21);
|
||||||
);
|
|
||||||
ElementPtr->state_flags &= ~IGNORE_SIMILAR;
|
ElementPtr->state_flags &= ~IGNORE_SIMILAR;
|
||||||
ElementPtr->state_flags |= CHANGING;
|
ElementPtr->state_flags |= CHANGING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((num_frames = WORLD_TO_TURN (
|
num_frames = WORLD_TO_TURN (
|
||||||
square_root ((long)delta_x * delta_x
|
square_root ((long)delta_x * delta_x
|
||||||
+ (long)delta_y * delta_y)
|
+ (long)delta_y * delta_y));
|
||||||
)) == 0)
|
if (num_frames == 0)
|
||||||
num_frames = 1;
|
num_frames = 1;
|
||||||
|
|
||||||
ShipVelocity = ObjectPtr->velocity;
|
ShipVelocity = ObjectPtr->velocity;
|
||||||
@@ -613,8 +609,7 @@ PELEMENT ElementPtr;
|
|||||||
- ElementPtr->current.location.y;
|
- ElementPtr->current.location.y;
|
||||||
|
|
||||||
delta_facing = NORMALIZE_FACING (
|
delta_facing = NORMALIZE_FACING (
|
||||||
ANGLE_TO_FACING (ARCTAN (delta_x, delta_y)) - facing
|
ANGLE_TO_FACING (ARCTAN (delta_x, delta_y)) - facing);
|
||||||
);
|
|
||||||
|
|
||||||
if (delta_facing > 0)
|
if (delta_facing > 0)
|
||||||
{
|
{
|
||||||
@@ -644,7 +639,8 @@ PELEMENT ElementPtr;
|
|||||||
|
|
||||||
OldFacing = StarShipPtr->ShipFacing;
|
OldFacing = StarShipPtr->ShipFacing;
|
||||||
OldStatus = StarShipPtr->cur_status_flags;
|
OldStatus = StarShipPtr->cur_status_flags;
|
||||||
OldIncrement = StarShipPtr->RaceDescPtr->characteristics.thrust_increment;
|
OldIncrement = StarShipPtr->RaceDescPtr->characteristics.
|
||||||
|
thrust_increment;
|
||||||
OldThrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust;
|
OldThrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust;
|
||||||
|
|
||||||
StarShipPtr->ShipFacing = facing;
|
StarShipPtr->ShipFacing = facing;
|
||||||
@@ -655,7 +651,8 @@ PELEMENT ElementPtr;
|
|||||||
thrust_status = inertial_thrust (ElementPtr);
|
thrust_status = inertial_thrust (ElementPtr);
|
||||||
|
|
||||||
StarShipPtr->RaceDescPtr->characteristics.max_thrust = OldThrust;
|
StarShipPtr->RaceDescPtr->characteristics.max_thrust = OldThrust;
|
||||||
StarShipPtr->RaceDescPtr->characteristics.thrust_increment = OldIncrement;
|
StarShipPtr->RaceDescPtr->characteristics.thrust_increment =
|
||||||
|
OldIncrement;
|
||||||
StarShipPtr->cur_status_flags = OldStatus;
|
StarShipPtr->cur_status_flags = OldStatus;
|
||||||
StarShipPtr->ShipFacing = OldFacing;
|
StarShipPtr->ShipFacing = OldFacing;
|
||||||
|
|
||||||
@@ -677,15 +674,16 @@ PELEMENT ElementPtr;
|
|||||||
|
|
||||||
InsertElement (hIonElement, GetHeadElement ());
|
InsertElement (hIonElement, GetHeadElement ());
|
||||||
LockElement (hIonElement, &IonElementPtr);
|
LockElement (hIonElement, &IonElementPtr);
|
||||||
IonElementPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID;
|
IonElementPtr->state_flags =
|
||||||
IonElementPtr->life_span = IonElementPtr->thrust_wait = ION_LIFE;
|
APPEARING | FINITE_LIFE | NONSOLID;
|
||||||
|
IonElementPtr->life_span =
|
||||||
|
IonElementPtr->thrust_wait = ION_LIFE;
|
||||||
SetPrimType (&(GLOBAL (DisplayArray))[
|
SetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
IonElementPtr->PrimIndex
|
IonElementPtr->PrimIndex], POINT_PRIM);
|
||||||
], POINT_PRIM);
|
|
||||||
SetPrimColor (&(GLOBAL (DisplayArray))[
|
SetPrimColor (&(GLOBAL (DisplayArray))[
|
||||||
IonElementPtr->PrimIndex
|
IonElementPtr->PrimIndex], START_ION_COLOR);
|
||||||
], START_ION_COLOR);
|
IonElementPtr->current.location =
|
||||||
IonElementPtr->current.location = ElementPtr->current.location;
|
ElementPtr->current.location;
|
||||||
IonElementPtr->current.location.x +=
|
IonElementPtr->current.location.x +=
|
||||||
(COORD)COSINE (angle, DISPLAY_TO_WORLD (2));
|
(COORD)COSINE (angle, DISPLAY_TO_WORLD (2));
|
||||||
IonElementPtr->current.location.y +=
|
IonElementPtr->current.location.y +=
|
||||||
@@ -786,7 +784,8 @@ marine_collision (PELEMENT ElementPtr0, PPOINT pPt0, PELEMENT ElementPtr1, PPOIN
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProcessSound (SetAbsSoundIndex (
|
ProcessSound (SetAbsSoundIndex (
|
||||||
StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr1);
|
StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2),
|
||||||
|
ElementPtr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementPtr0->state_flags &= ~COLLISION;
|
ElementPtr0->state_flags &= ~COLLISION;
|
||||||
@@ -819,8 +818,7 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
STARSHIPPTR StarShipPtr;
|
STARSHIPPTR StarShipPtr;
|
||||||
|
|
||||||
SetPrimType (&(GLOBAL (DisplayArray))[
|
SetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
ElementPtr->PrimIndex
|
ElementPtr->PrimIndex], NO_PRIM);
|
||||||
], NO_PRIM);
|
|
||||||
|
|
||||||
GetElementStarShip (ElementPtr, &StarShipPtr);
|
GetElementStarShip (ElementPtr, &StarShipPtr);
|
||||||
if (StarShipPtr->hShip)
|
if (StarShipPtr->hShip)
|
||||||
@@ -866,8 +864,7 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
<< (NORMALIZE_FACING (facing + ANGLE_TO_FACING (OCTANT))
|
<< (NORMALIZE_FACING (facing + ANGLE_TO_FACING (OCTANT))
|
||||||
/ ANGLE_TO_FACING (QUADRANT));
|
/ ANGLE_TO_FACING (QUADRANT));
|
||||||
TurretPtr->current.image.frame = SetAbsFrameIndex (
|
TurretPtr->current.image.frame = SetAbsFrameIndex (
|
||||||
TurretPtr->current.image.frame, facing
|
TurretPtr->current.image.frame, facing);
|
||||||
);
|
|
||||||
facing = FACING_TO_ANGLE (facing);
|
facing = FACING_TO_ANGLE (facing);
|
||||||
if (StarShipPtr->cur_status_flags & WEAPON)
|
if (StarShipPtr->cur_status_flags & WEAPON)
|
||||||
{
|
{
|
||||||
@@ -876,14 +873,14 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
|
|
||||||
LockElement (GetTailElement (), &TurretEffectPtr);
|
LockElement (GetTailElement (), &TurretEffectPtr);
|
||||||
if ((PELEMENT)TurretEffectPtr != ElementPtr
|
if ((PELEMENT)TurretEffectPtr != ElementPtr
|
||||||
&& (TurretEffectPtr->state_flags & (GOOD_GUY | BAD_GUY)) ==
|
&& (TurretEffectPtr->state_flags &
|
||||||
|
(GOOD_GUY | BAD_GUY)) ==
|
||||||
(ElementPtr->state_flags & (GOOD_GUY | BAD_GUY))
|
(ElementPtr->state_flags & (GOOD_GUY | BAD_GUY))
|
||||||
&& (TurretEffectPtr->state_flags & APPEARING)
|
&& (TurretEffectPtr->state_flags & APPEARING)
|
||||||
&& GetPrimType (&(GLOBAL (DisplayArray))[
|
&& GetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
TurretEffectPtr->PrimIndex
|
TurretEffectPtr->PrimIndex
|
||||||
]) == STAMP_PRIM
|
]) == STAMP_PRIM
|
||||||
&& (hTurretEffect = AllocElement ())
|
&& (hTurretEffect = AllocElement ()))
|
||||||
)
|
|
||||||
{
|
{
|
||||||
TurretPtr->current.location.x -=
|
TurretPtr->current.location.x -=
|
||||||
COSINE (facing, DISPLAY_TO_WORLD (2));
|
COSINE (facing, DISPLAY_TO_WORLD (2));
|
||||||
@@ -891,9 +888,10 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
SINE (facing, DISPLAY_TO_WORLD (2));
|
SINE (facing, DISPLAY_TO_WORLD (2));
|
||||||
|
|
||||||
LockElement (hTurretEffect, &TurretEffectPtr);
|
LockElement (hTurretEffect, &TurretEffectPtr);
|
||||||
TurretEffectPtr->state_flags =
|
TurretEffectPtr->state_flags = FINITE_LIFE
|
||||||
FINITE_LIFE | NONSOLID | IGNORE_SIMILAR | APPEARING
|
| NONSOLID | IGNORE_SIMILAR | APPEARING
|
||||||
| (ElementPtr->state_flags & (GOOD_GUY | BAD_GUY));
|
| (ElementPtr->state_flags &
|
||||||
|
(GOOD_GUY | BAD_GUY));
|
||||||
TurretEffectPtr->life_span = 4;
|
TurretEffectPtr->life_span = 4;
|
||||||
|
|
||||||
TurretEffectPtr->current.location.x =
|
TurretEffectPtr->current.location.x =
|
||||||
@@ -906,18 +904,17 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
DISPLAY_TO_WORLD (TURRET_OFFSET));
|
DISPLAY_TO_WORLD (TURRET_OFFSET));
|
||||||
TurretEffectPtr->current.image.farray =
|
TurretEffectPtr->current.image.farray =
|
||||||
StarShipPtr->RaceDescPtr->ship_data.special;
|
StarShipPtr->RaceDescPtr->ship_data.special;
|
||||||
TurretEffectPtr->current.image.frame = SetAbsFrameIndex (
|
TurretEffectPtr->current.image.frame =
|
||||||
|
SetAbsFrameIndex (
|
||||||
StarShipPtr->RaceDescPtr->ship_data.special[0],
|
StarShipPtr->RaceDescPtr->ship_data.special[0],
|
||||||
ANGLE_TO_FACING (FULL_CIRCLE)
|
ANGLE_TO_FACING (FULL_CIRCLE));
|
||||||
);
|
|
||||||
|
|
||||||
TurretEffectPtr->preprocess_func = animate;
|
TurretEffectPtr->preprocess_func = animate;
|
||||||
|
|
||||||
SetElementStarShip (TurretEffectPtr, StarShipPtr);
|
SetElementStarShip (TurretEffectPtr, StarShipPtr);
|
||||||
|
|
||||||
SetPrimType (&(GLOBAL (DisplayArray))[
|
SetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
TurretEffectPtr->PrimIndex
|
TurretEffectPtr->PrimIndex], STAMP_PRIM);
|
||||||
], STAMP_PRIM);
|
|
||||||
|
|
||||||
UnlockElement (hTurretEffect);
|
UnlockElement (hTurretEffect);
|
||||||
PutElement (hTurretEffect);
|
PutElement (hTurretEffect);
|
||||||
@@ -927,20 +924,15 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
TurretPtr->next = TurretPtr->current;
|
TurretPtr->next = TurretPtr->current;
|
||||||
|
|
||||||
SetPrimType (&(GLOBAL (DisplayArray))[
|
SetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
TurretPtr->PrimIndex
|
TurretPtr->PrimIndex],
|
||||||
],
|
|
||||||
GetPrimType (&(GLOBAL (DisplayArray))[
|
GetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
ShipPtr->PrimIndex
|
ShipPtr->PrimIndex]));
|
||||||
]));
|
|
||||||
SetPrimColor (&(GLOBAL (DisplayArray))[
|
SetPrimColor (&(GLOBAL (DisplayArray))[
|
||||||
TurretPtr->PrimIndex
|
TurretPtr->PrimIndex],
|
||||||
],
|
|
||||||
GetPrimColor (&(GLOBAL (DisplayArray))[
|
GetPrimColor (&(GLOBAL (DisplayArray))[
|
||||||
ShipPtr->PrimIndex
|
ShipPtr->PrimIndex]));
|
||||||
]));
|
|
||||||
|
|
||||||
TurretPtr->postprocess_func =
|
TurretPtr->postprocess_func = ElementPtr->postprocess_func;
|
||||||
ElementPtr->postprocess_func;
|
|
||||||
|
|
||||||
SetElementStarShip (TurretPtr, StarShipPtr);
|
SetElementStarShip (TurretPtr, StarShipPtr);
|
||||||
|
|
||||||
@@ -969,37 +961,33 @@ turret_postprocess (PELEMENT ElementPtr)
|
|||||||
facing = FACING_TO_ANGLE (StarShipPtr->ShipFacing);
|
facing = FACING_TO_ANGLE (StarShipPtr->ShipFacing);
|
||||||
SpaceMarinePtr->current.location.x =
|
SpaceMarinePtr->current.location.x =
|
||||||
ShipPtr->current.location.x
|
ShipPtr->current.location.x
|
||||||
- COSINE (facing,
|
- COSINE (facing, DISPLAY_TO_WORLD (TURRET_OFFSET));
|
||||||
DISPLAY_TO_WORLD (TURRET_OFFSET));
|
|
||||||
SpaceMarinePtr->current.location.y =
|
SpaceMarinePtr->current.location.y =
|
||||||
ShipPtr->current.location.y
|
ShipPtr->current.location.y
|
||||||
- SINE (facing,
|
- SINE (facing, DISPLAY_TO_WORLD (TURRET_OFFSET));
|
||||||
DISPLAY_TO_WORLD (TURRET_OFFSET));
|
|
||||||
SpaceMarinePtr->current.image.farray =
|
SpaceMarinePtr->current.image.farray =
|
||||||
StarShipPtr->RaceDescPtr->ship_data.special;
|
StarShipPtr->RaceDescPtr->ship_data.special;
|
||||||
SpaceMarinePtr->current.image.frame = SetAbsFrameIndex (
|
SpaceMarinePtr->current.image.frame = SetAbsFrameIndex (
|
||||||
StarShipPtr->RaceDescPtr->ship_data.special[0], 20
|
StarShipPtr->RaceDescPtr->ship_data.special[0], 20);
|
||||||
);
|
|
||||||
|
|
||||||
SpaceMarinePtr->turn_wait = MAKE_BYTE (0,
|
SpaceMarinePtr->turn_wait =
|
||||||
NORMALIZE_FACING (
|
MAKE_BYTE (0, NORMALIZE_FACING (
|
||||||
ANGLE_TO_FACING (facing + HALF_CIRCLE)
|
ANGLE_TO_FACING (facing + HALF_CIRCLE)));
|
||||||
));
|
|
||||||
SpaceMarinePtr->preprocess_func = marine_preprocess;
|
SpaceMarinePtr->preprocess_func = marine_preprocess;
|
||||||
SpaceMarinePtr->collision_func = marine_collision;
|
SpaceMarinePtr->collision_func = marine_collision;
|
||||||
|
|
||||||
SetElementStarShip (SpaceMarinePtr, StarShipPtr);
|
SetElementStarShip (SpaceMarinePtr, StarShipPtr);
|
||||||
|
|
||||||
SetPrimType (&(GLOBAL (DisplayArray))[
|
SetPrimType (&(GLOBAL (DisplayArray))[
|
||||||
SpaceMarinePtr->PrimIndex
|
SpaceMarinePtr->PrimIndex], STAMP_PRIM);
|
||||||
], STAMP_PRIM);
|
|
||||||
|
|
||||||
UnlockElement (hSpaceMarine);
|
UnlockElement (hSpaceMarine);
|
||||||
PutElement (hSpaceMarine);
|
PutElement (hSpaceMarine);
|
||||||
|
|
||||||
DeltaCrew (ShipPtr, -1);
|
DeltaCrew (ShipPtr, -1);
|
||||||
ProcessSound (SetAbsSoundIndex (
|
ProcessSound (SetAbsSoundIndex (
|
||||||
StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), SpaceMarinePtr);
|
StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1),
|
||||||
|
SpaceMarinePtr);
|
||||||
|
|
||||||
StarShipPtr->special_counter =
|
StarShipPtr->special_counter =
|
||||||
StarShipPtr->RaceDescPtr->characteristics.special_wait;
|
StarShipPtr->RaceDescPtr->characteristics.special_wait;
|
||||||
|
|||||||
Reference in New Issue
Block a user