uio_access() work in progress. Commented out for now.

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3208 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
Meep-Eep
2009-10-08 21:17:42 +00:00
parent fc1fbac82a
commit 83949a60dc
7 changed files with 233 additions and 2 deletions
+3
View File
@@ -57,6 +57,9 @@ Bugs:
- Network paths on Windows are not accepted.
- No CRLF translation (and ^Z recognition) is done for files read from
zip files, even though that may be expected on Windows.
- The order in which "uio_unmountAllDirs() unmounts the directories, may lead
it to unmount a dir while there still is a file descriptor for another
dir open, causing a warning.
Extra features (not necessary for UQM):
- Make functions to use for uio_malloc, uio_free and uio_realloc
+1
View File
@@ -59,6 +59,7 @@ struct uio_FileSystemHandler {
struct uio_PRoot * (*mount) (uio_Handle *, int);
int (*umount) (uio_PRoot *);
int (*access) (uio_PDirHandle *, const char *, int mode);
void (*close) (uio_Handle *);
// called when the last reference is closed, not
// necessarilly each time when uio_close() is called
+140
View File
@@ -39,6 +39,10 @@
# include "memdebug.h"
#endif
#if 0
static int uio_accessDir(uio_DirHandle *dirHandle, const char *path,
int mode);
#endif
static int uio_statDir(uio_DirHandle *dirHandle, const char *path,
struct stat *statBuf);
static int uio_statOneDir(uio_PDirHandle *pDirHandle, struct stat *statBuf);
@@ -414,6 +418,134 @@ uio_rename(uio_DirHandle *oldDir, const char *oldPath,
return 0;
}
int
uio_access(uio_DirHandle *dir, const char *path, int mode) {
(void) dir;
(void) path;
(void) mode;
errno = ENOSYS; // Not implemented.
return -1;
#if 0
uio_PDirHandle *pReadDir;
uio_MountInfo *readMountInfo;
char *name;
int result;
if (uio_getPhysicalAccess(dir, path, O_RDONLY, 0,
&readMountInfo, &pReadDir, NULL,
NULL, NULL, NULL, &name) == -1) {
// XXX: I copied this part from uio_stat(). Is this what I need?
if (uio_accessDir(dir, path, statBuf) == -1) {
// errno is set
return -1;
}
return 0;
}
if (pReadDir->pRoot->handler->access == NULL) {
uio_PDirHandle_unref(pReadDir);
uio_free(name);
errno = ENOSYS;
return -1;
}
result = (pReadDir->pRoot->handler->access)(pReadDir, name, mode);
if (result == -1) {
int savedErrno = errno;
uio_PDirHandle_unref(pReadDir);
uio_free(name);
errno = savedErrno;
return -1;
}
uio_PDirHandle_unref(pReadDir);
uio_free(name);
return result;
#endif
}
#if 0
// auxiliary function to uio_access
static int
uio_accessDir(uio_DirHandle *dirHandle, const char *path, int mode) {
int numPDirHandles;
uio_PDirHandle **pDirHandles;
if (mode & R_OK)
{
// Read permission is always granted. Nothing to check here.
}
if (uio_getPathPhysicalDirs(dirHandle, path, strlen(path),
&pDirHandles, &numPDirHandles, NULL) == -1) {
// errno is set
return -1;
}
if (numPDirHandles == 0) {
errno = ENOENT;
return -1;
}
if (mode & F_OK)
{
// We need to check whether each of the directories is complete
// WORK
}
if (mode & W_OK) {
// If there is any directory where writing is allowed, then
// we can write.
// WORK
errno = ENOENT;
return -1;
#if 0
if (uio_statOneDir(pDirHandles[0], statBuf) == -1) {
int savedErrno = errno;
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
errno = savedErrno;
return -1;
}
// TODO: atm, fstat'ing a dir will show the info for the topmost
// dir. Maybe it would make sense of merging the bits. (How?)
#if 0
for (i = 1; i < numPDirHandles; i++) {
struct stat statOne;
uio_PDirHandle *pDirHandle;
if (statOneDir(pDirHandles[i], &statOne) == -1) {
// errno is set
int savedErrno = errno;
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
errno = savedErrno;
return -1;
}
// Merge dirs:
}
#endif
#endif
}
if (mode & X_OK) {
// XXX: Not implemented.
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
errno = ENOSYS;
return -1;
}
uio_PDirHandles_delete(pDirHandles, numPDirHandles);
return 0;
}
#endif
int
uio_fstat(uio_Handle *handle, struct stat *statBuf) {
if (handle->root->handler->fstat == NULL) {
@@ -448,6 +580,14 @@ uio_stat(uio_DirHandle *dir, const char *path, struct stat *statBuf) {
}
result = (pReadDir->pRoot->handler->stat)(pReadDir, name, statBuf);
if (result == -1) {
int savedErrno = errno;
uio_PDirHandle_unref(pReadDir);
uio_free(name);
errno = savedErrno;
return -1;
}
uio_PDirHandle_unref(pReadDir);
uio_free(name);
return result;
+24
View File
@@ -70,6 +70,7 @@ uio_FileSystemHandler stdio_fileSystemHandler = {
/* .mount = */ stdio_mount,
/* .umount = */ uio_GPRoot_umount,
/* .access = */ stdio_access,
/* .close = */ stdio_close,
/* .fstat = */ stdio_fstat,
/* .stat = */ stdio_stat,
@@ -120,6 +121,29 @@ stdio_close(uio_Handle *handle) {
}
}
int
stdio_access(uio_PDirHandle *pDirHandle, const char *name, int mode) {
char *path;
int result;
path = joinPaths(stdio_getPath(pDirHandle->extra), name);
if (path == NULL) {
// errno is set
return -1;
}
result = access(path, mode);
if (result == -1) {
int savedErrno = errno;
uio_free(path);
errno = savedErrno;
return -1;
}
uio_free(path);
return result;
}
int
stdio_fstat(uio_Handle *handle, struct stat *statBuf) {
return fstat(handle->native->fd, statBuf);
+2
View File
@@ -83,6 +83,8 @@ uio_PDirHandle *stdio_mkdir(uio_PDirHandle *pDirHandle, const char *name,
uio_Handle *stdio_open(uio_PDirHandle *pDirHandle, const char *file, int flags,
mode_t mode);
void stdio_close(uio_Handle *handle);
int zip_access(uio_PDirHandle *pDirHandle, const char *name, int mode);
int stdio_access(uio_PDirHandle *pDirHandle, const char *name, int mode);
int stdio_fstat(uio_Handle *handle, struct stat *statBuf);
int stdio_stat(uio_PDirHandle *pDirHandle, const char *name,
struct stat *statBuf);
+54 -2
View File
@@ -98,6 +98,7 @@ uio_FileSystemHandler zip_fileSystemHandler = {
/* .mount = */ zip_mount,
/* .umount = */ uio_GPRoot_umount,
/* .access = */ zip_access,
/* .close = */ zip_close,
/* .fstat = */ zip_fstat,
/* .stat = */ zip_stat,
@@ -218,6 +219,55 @@ zip_fillStat(struct stat *statBuf, const zip_GPFileData *gPFileData) {
statBuf->st_ctime = gPFileData->ctime;
}
int
zip_access(uio_PDirHandle *pDirHandle, const char *name, int mode) {
errno = ENOSYS; // Not implemented.
(void) pDirHandle;
(void) name;
(void) mode;
return -1;
#if 0
uio_GPDirEntry *entry;
if (name[0] == '.' && name[1] == '\0') {
entry = (uio_GPDirEntry *) pDirHandle->extra;
} else {
entry = uio_GPDir_getGPDirEntry(pDirHandle->extra, name);
if (entry == NULL) {
errno = ENOENT;
return -1;
}
}
if (mode & R_OK)
{
// Read permission is always granted. Nothing to check here.
}
if (mode & W_OK) {
errno = EACCES;
return -1;
}
if (mode & X_OK) {
if (uio_GPDirEntry_isDir(entry)) {
// Search permission on directories is always granted.
} else {
// WORK
#error
}
}
if (mode & F_OK) {
// WORK
#error
}
return 0;
#endif
}
int
zip_fstat(uio_Handle *handle, struct stat *statBuf) {
#if zip_USE_HEADERS == zip_USE_CENTRAL_HEADERS
@@ -229,7 +279,7 @@ zip_fstat(uio_Handle *handle, struct stat *statBuf) {
return -1;
}
}
#endif
#endif /* zip_USE_HEADERS == zip_USE_CENTRAL_HEADERS */
zip_fillStat(statBuf, handle->native->file->extra);
return 0;
}
@@ -261,6 +311,7 @@ zip_stat(uio_PDirHandle *pDirHandle, const char *name, struct stat *statBuf) {
}
#if zip_USE_HEADERS == zip_USE_CENTRAL_HEADERS
#ifndef zip_INCOMPLETE_STAT
if (((zip_GPFileData *) entry->extra)->fileOffset == -1) {
// The local header wasn't read in yet.
if (zip_updateFileDataFromLocalHeader(pDirHandle->pRoot->handle,
@@ -269,7 +320,8 @@ zip_stat(uio_PDirHandle *pDirHandle, const char *name, struct stat *statBuf) {
return -1;
}
}
#endif
#endif /* !defined(zip_INCOMPLETE_STAT) */
#endif /* zip_USE_HEADERS == zip_USE_CENTRAL_HEADERS */
zip_fillStat(statBuf, (zip_GPFileData *) entry->extra);
return 0;
+9
View File
@@ -47,6 +47,14 @@ typedef struct uio_GPDirEntries_Iterator *uio_NativeEntriesContext;
#define zip_USE_CENTRAL_HEADERS 1
#define zip_USE_LOCAL_HEADERS 2
#define zip_INCOMPLETE_STAT
// Ignored unless zip_USE_HEADERS == zip_USE_CENTRAL_HEADERS.
// If defined, extra meta-data for files in the .zip archive
// isn't retrieved from the local file header when zip_stat()
// is called. The uid, gid, file mode, and file times may be
// inaccurate. The advantage is that a possibly costly seek and
// read can be avoided.
typedef struct zip_GPFileData {
off_t compressedSize;
off_t uncompressedSize;
@@ -86,6 +94,7 @@ int zip_umount(struct uio_PRoot *);
uio_Handle *zip_open(uio_PDirHandle *pDirHandle, const char *file, int flags,
mode_t mode);
void zip_close(uio_Handle *handle);
int zip_access(uio_PDirHandle *pDirHandle, const char *name, int mode);
int zip_fstat(uio_Handle *handle, struct stat *statBuf);
int zip_stat(uio_PDirHandle *pDirHandle, const char *name,
struct stat *statBuf);