Compare commits
3 Commits
ea4aaca2a6
...
df51651789
Author | SHA1 | Date |
---|---|---|
~d6 | df51651789 | |
Devine Lu Linvega | 0da4c3335d | |
~d6 | e772d56936 |
|
@ -9,17 +9,20 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#include <direct.h>
|
||||||
#include <libiberty/libiberty.h>
|
#include <libiberty/libiberty.h>
|
||||||
#define realpath(s, dummy) lrealpath(s)
|
#define realpath(s, dummy) lrealpath(s)
|
||||||
#define DIR_SEP_CHAR '\\'
|
#define DIR_SEP_CHAR '\\'
|
||||||
#define DIR_SEP_STR "\\"
|
#define DIR_SEP_STR "\\"
|
||||||
#define pathcmp(path1, path2, length) strncasecmp(path1, path2, length) /* strncasecmp provided by libiberty */
|
#define pathcmp(path1, path2, length) strncasecmp(path1, path2, length) /* strncasecmp provided by libiberty */
|
||||||
#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR && ((strlen(file_name) > 2 && file_name[1] != ':') || strlen(file_name) <= 2))
|
#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR && ((strlen(file_name) > 2 && file_name[1] != ':') || strlen(file_name) <= 2))
|
||||||
|
#define mkdir(file_name) (_mkdir(file_name) == 0)
|
||||||
#else
|
#else
|
||||||
#define DIR_SEP_CHAR '/'
|
#define DIR_SEP_CHAR '/'
|
||||||
#define DIR_SEP_STR "/"
|
#define DIR_SEP_STR "/"
|
||||||
#define pathcmp(path1, path2, length) strncmp(path1, path2, length)
|
#define pathcmp(path1, path2, length) strncmp(path1, path2, length)
|
||||||
#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR)
|
#define notdriveroot(file_name) (file_name[0] != DIR_SEP_CHAR)
|
||||||
|
#define mkdir(file_name) (mkdir(file_name, 0755) == 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
|
@ -48,7 +51,9 @@ typedef struct {
|
||||||
enum { IDLE,
|
enum { IDLE,
|
||||||
FILE_READ,
|
FILE_READ,
|
||||||
FILE_WRITE,
|
FILE_WRITE,
|
||||||
DIR_READ } state;
|
DIR_READ,
|
||||||
|
DIR_WRITE
|
||||||
|
} state;
|
||||||
int outside_sandbox;
|
int outside_sandbox;
|
||||||
} UxnFile;
|
} UxnFile;
|
||||||
|
|
||||||
|
@ -207,33 +212,94 @@ file_read(UxnFile *c, void *dest, int len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_dir_path(char *p)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int saw_slash = 0;
|
||||||
|
while (c = *p++)
|
||||||
|
saw_slash = c == DIR_SEP_CHAR;
|
||||||
|
return saw_slash;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dir_exists(char *p)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return stat(p, &st) == 0 && S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ensure_parent_dirs(char *p)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
char c, *s = p;
|
||||||
|
for(; ok && (c = *p); p++) {
|
||||||
|
if (c == DIR_SEP_CHAR) {
|
||||||
|
*p = '\0';
|
||||||
|
ok = dir_exists(s) || mkdir(s);
|
||||||
|
*p = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
static Uint16
|
static Uint16
|
||||||
file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags)
|
file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags)
|
||||||
{
|
{
|
||||||
Uint16 ret = 0;
|
Uint16 ret = 0;
|
||||||
if(c->outside_sandbox) return 0;
|
if(c->outside_sandbox) return 0;
|
||||||
if(c->state != FILE_WRITE) {
|
ensure_parent_dirs(c->current_filename);
|
||||||
|
if(c->state != FILE_WRITE && c->state != DIR_WRITE) {
|
||||||
reset(c);
|
reset(c);
|
||||||
if((c->f = fopen(c->current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL)
|
if (is_dir_path(c->current_filename))
|
||||||
|
c->state = DIR_WRITE;
|
||||||
|
else if((c->f = fopen(c->current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL)
|
||||||
c->state = FILE_WRITE;
|
c->state = FILE_WRITE;
|
||||||
}
|
}
|
||||||
if(c->state == FILE_WRITE) {
|
if(c->state == FILE_WRITE) {
|
||||||
if((ret = fwrite(src, 1, len, c->f)) > 0 && fflush(c->f) != 0)
|
if((ret = fwrite(src, 1, len, c->f)) > 0 && fflush(c->f) != 0)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
if (c->state == DIR_WRITE) {
|
||||||
|
ret = dir_exists(c->current_filename);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Uint16
|
||||||
|
stat_fill(Uint8 *dest, Uint16 len, char c)
|
||||||
|
{
|
||||||
|
Uint16 i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
*(dest++) = c;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint16
|
||||||
|
stat_size(Uint8 *dest, Uint16 len, off_t size)
|
||||||
|
{
|
||||||
|
Uint16 i;
|
||||||
|
dest += len - 1;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
*(dest--) = '0' + (Uint8)(size & 0xf);
|
||||||
|
size = size >> 4;
|
||||||
|
}
|
||||||
|
return size == 0 ? len : stat_fill(dest, len, '?');
|
||||||
|
}
|
||||||
|
|
||||||
static Uint16
|
static Uint16
|
||||||
file_stat(UxnFile *c, void *dest, Uint16 len)
|
file_stat(UxnFile *c, void *dest, Uint16 len)
|
||||||
{
|
{
|
||||||
char *basename = strrchr(c->current_filename, DIR_SEP_CHAR);
|
struct stat st;
|
||||||
if(c->outside_sandbox) return 0;
|
if(c->outside_sandbox)
|
||||||
if(basename != NULL)
|
return 0;
|
||||||
basename++;
|
else if(stat(c->current_filename, &st))
|
||||||
|
return stat_fill(dest, len, '!');
|
||||||
|
else if(S_ISDIR(st.st_mode))
|
||||||
|
return stat_fill(dest, len, '-');
|
||||||
else
|
else
|
||||||
basename = c->current_filename;
|
return stat_size(dest, len, st.st_size);
|
||||||
return get_entry(dest, len, c->current_filename, basename, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint16
|
static Uint16
|
||||||
|
|
Loading…
Reference in New Issue