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