clean up directory entries
This commit is contained in:
parent
7fcd7ad635
commit
1998e6cccc
|
@ -76,26 +76,62 @@ reset(UxnFile *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint16
|
static Uint16
|
||||||
get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int fail_nonzero)
|
stat_fill(Uint16 addr, Uint16 len, char c)
|
||||||
{
|
{
|
||||||
struct stat st;
|
Uint16 i;
|
||||||
if(len < strlen(basename) + 8)
|
for (i = 0; i < len; i++)
|
||||||
return 0;
|
uxn.ram[(addr + i) & 0xffff] = c;
|
||||||
if(stat(pathname, &st))
|
return len;
|
||||||
return fail_nonzero ? snprintf(p, len, "!!!! %s\n", basename) : 0;
|
|
||||||
else if(S_ISDIR(st.st_mode))
|
|
||||||
return snprintf(p, len, "---- %s/\n", basename);
|
|
||||||
else if(st.st_size < 0x10000)
|
|
||||||
return snprintf(p, len, "%04x %s\n", (unsigned int)st.st_size, basename);
|
|
||||||
else
|
|
||||||
return snprintf(p, len, "???? %s\n", basename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint16
|
static Uint16
|
||||||
file_read_dir(UxnFile *c, char *dest, Uint16 len)
|
stat_size(Uint16 addr, Uint16 len, off_t size)
|
||||||
|
{
|
||||||
|
Uint16 i;
|
||||||
|
for (i = 1; i <= len; i++) {
|
||||||
|
char c = '0' + (Uint8)(size & 0xf);
|
||||||
|
uxn.ram[(addr + len - i) & 0xffff] = c;
|
||||||
|
size = size >> 4;
|
||||||
|
}
|
||||||
|
if (size > 0)
|
||||||
|
stat_fill(addr, len, '?');
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint16
|
||||||
|
stat_entry(Uint16 addr, char sym, off_t size, const char *s)
|
||||||
|
{
|
||||||
|
Uint16 pos = addr;
|
||||||
|
pos += sym ? stat_fill(pos, 4, sym) : stat_size(pos, 4, size);
|
||||||
|
uxn.ram[(pos++) & 0xffff] = ' ';
|
||||||
|
while(*s)
|
||||||
|
uxn.ram[(pos++) & 0xffff] = *(s++);
|
||||||
|
uxn.ram[(pos++) & 0xffff] = '\n';
|
||||||
|
/* like printf and friends, we don't count the trailing null */
|
||||||
|
uxn.ram[pos & 0xffff] = '\0';
|
||||||
|
return pos - addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint16
|
||||||
|
get_entry(Uint16 addr, Uint16 len, const char *pathname, const char *basename)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if(len < strlen(basename) + 8) return 0;
|
||||||
|
char sym = 0;
|
||||||
|
off_t size = 0;
|
||||||
|
if(stat(pathname, &st)) sym = '!';
|
||||||
|
else if(S_ISDIR(st.st_mode)) sym = '-';
|
||||||
|
else if(st.st_size >= 0x10000) sym = '?';
|
||||||
|
else size = st.st_size;
|
||||||
|
return stat_entry(addr, sym, size, basename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint16
|
||||||
|
file_read_dir(UxnFile *c, Uint16 addr, Uint16 len)
|
||||||
{
|
{
|
||||||
static char pathname[4352];
|
static char pathname[4352];
|
||||||
char *p = dest;
|
Uint16 pos = addr;
|
||||||
|
char cwd[PATH_MAX] = {'\0'}, *t;
|
||||||
if(c->de == NULL) c->de = readdir(c->dir);
|
if(c->de == NULL) c->de = readdir(c->dir);
|
||||||
for(; c->de != NULL; c->de = readdir(c->dir)) {
|
for(; c->de != NULL; c->de = readdir(c->dir)) {
|
||||||
Uint16 n;
|
Uint16 n;
|
||||||
|
@ -103,7 +139,6 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
|
||||||
continue;
|
continue;
|
||||||
if(strcmp(c->de->d_name, "..") == 0) {
|
if(strcmp(c->de->d_name, "..") == 0) {
|
||||||
/* hide "sandbox/.." */
|
/* hide "sandbox/.." */
|
||||||
char cwd[PATH_MAX] = {'\0'}, *t;
|
|
||||||
/* Note there's [currently] no way of chdir()ing from uxn, so $PWD
|
/* Note there's [currently] no way of chdir()ing from uxn, so $PWD
|
||||||
* is always the sandbox top level. */
|
* is always the sandbox top level. */
|
||||||
getcwd(cwd, sizeof(cwd));
|
getcwd(cwd, sizeof(cwd));
|
||||||
|
@ -119,12 +154,12 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
|
||||||
snprintf(pathname, sizeof(pathname), "%s/%s", c->current_filename, c->de->d_name);
|
snprintf(pathname, sizeof(pathname), "%s/%s", c->current_filename, c->de->d_name);
|
||||||
else
|
else
|
||||||
pathname[0] = '\0';
|
pathname[0] = '\0';
|
||||||
n = get_entry(p, len, pathname, c->de->d_name, 1);
|
n = get_entry(pos, len, pathname, c->de->d_name);
|
||||||
if(!n) break;
|
if(!n) break;
|
||||||
p += n;
|
pos += n;
|
||||||
len -= n;
|
len -= n;
|
||||||
}
|
}
|
||||||
return p - dest;
|
return pos - addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -221,7 +256,7 @@ file_read(UxnFile *c, Uint16 addr, int len)
|
||||||
if(c->state == FILE_READ)
|
if(c->state == FILE_READ)
|
||||||
return file_read_file(addr, len, c->f);
|
return file_read_file(addr, len, c->f);
|
||||||
if(c->state == DIR_READ)
|
if(c->state == DIR_READ)
|
||||||
return file_read_dir(c, (char *)&uxn.ram[addr], len);
|
return file_read_dir(c, addr, len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,27 +328,6 @@ file_write(UxnFile *c, Uint16 addr, Uint16 len, Uint8 flags)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint16
|
|
||||||
stat_fill(Uint16 addr, Uint16 len, char c)
|
|
||||||
{
|
|
||||||
Uint16 i;
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
uxn.ram[(addr + i) & 0xffff] = c;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Uint16
|
|
||||||
stat_size(Uint16 addr, Uint16 len, off_t size)
|
|
||||||
{
|
|
||||||
Uint16 i;
|
|
||||||
for (i = 1; i <= len; i++) {
|
|
||||||
char c = '0' + (Uint8)(size & 0xf);
|
|
||||||
uxn.ram[(addr + len - i) & 0xffff] = c;
|
|
||||||
size = size >> 4;
|
|
||||||
}
|
|
||||||
return size == 0 ? len : stat_fill(addr, len, '?');
|
|
||||||
}
|
|
||||||
|
|
||||||
static Uint16
|
static Uint16
|
||||||
file_stat(UxnFile *c, Uint16 addr, Uint16 len)
|
file_stat(UxnFile *c, Uint16 addr, Uint16 len)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue