Merge latest TomB version as of 6 April
This commit is contained in:
parent
dcb6ab5053
commit
d8ba1f9037
240 changed files with 125165 additions and 108915 deletions
425
src/fsdb.cpp
425
src/fsdb.cpp
|
@ -13,8 +13,8 @@
|
|||
#include "options.h"
|
||||
#include "uae.h"
|
||||
#include "memory.h"
|
||||
#include "custom.h"
|
||||
#include "newcpu.h"
|
||||
#include "custom.h"
|
||||
#include "filesys.h"
|
||||
#include "autoconf.h"
|
||||
#include "fsusage.h"
|
||||
|
@ -35,12 +35,12 @@
|
|||
#define TRACE(x)
|
||||
#endif
|
||||
|
||||
char *nname_begin (char *nname)
|
||||
TCHAR *nname_begin (TCHAR *nname)
|
||||
{
|
||||
char *p = strrchr (nname, FSDB_DIR_SEPARATOR);
|
||||
if (p)
|
||||
return p + 1;
|
||||
return nname;
|
||||
TCHAR *p = _tcsrchr (nname, FSDB_DIR_SEPARATOR);
|
||||
if (p)
|
||||
return p + 1;
|
||||
return nname;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -49,296 +49,301 @@ char *nname_begin (char *nname)
|
|||
* has the same name when compared case-insensitively, return a
|
||||
* malloced string that contains the name we found. If no file
|
||||
* exists that compares equal to REL, return 0. */
|
||||
char *fsdb_search_dir (const char *dirname, char *rel)
|
||||
TCHAR *fsdb_search_dir (const TCHAR *dirname, TCHAR *rel)
|
||||
{
|
||||
char *p = 0;
|
||||
int de;
|
||||
void *dir;
|
||||
char fn[MAX_DPATH];
|
||||
TCHAR *p = 0;
|
||||
int de;
|
||||
struct my_opendir_s *dir;
|
||||
TCHAR fn[MAX_DPATH];
|
||||
|
||||
dir = my_opendir (dirname);
|
||||
/* This really shouldn't happen... */
|
||||
if (! dir)
|
||||
return 0;
|
||||
dir = my_opendir (dirname);
|
||||
/* This really shouldn't happen... */
|
||||
if (! dir)
|
||||
return 0;
|
||||
|
||||
while (p == 0 && (de = my_readdir (dir, fn)) != 0) {
|
||||
if (strcmp (fn, rel) == 0)
|
||||
while (p == 0 && (de = my_readdir (dir, fn)) != 0) {
|
||||
if (strcmp (fn, rel) == 0)
|
||||
p = rel;
|
||||
else if (strcasecmp (fn, rel) == 0)
|
||||
p = my_strdup (fn);
|
||||
}
|
||||
my_closedir (dir);
|
||||
return p;
|
||||
else if (strcasecmp (fn, rel) == 0)
|
||||
p = my_strdup (fn);
|
||||
}
|
||||
my_closedir (dir);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
static FILE *get_fsdb (a_inode *dir, const char *mode)
|
||||
static FILE *get_fsdb (a_inode *dir, const TCHAR *mode)
|
||||
{
|
||||
char *n;
|
||||
FILE *f;
|
||||
TCHAR *n;
|
||||
FILE *f;
|
||||
|
||||
n = build_nname (dir->nname, FSDB_FILE);
|
||||
f = fopen (n, mode);
|
||||
free (n);
|
||||
return f;
|
||||
if (!dir->nname)
|
||||
return NULL;
|
||||
n = build_nname (dir->nname, FSDB_FILE);
|
||||
f = _tfopen (n, mode);
|
||||
xfree (n);
|
||||
return f;
|
||||
}
|
||||
|
||||
static void kill_fsdb (a_inode *dir)
|
||||
{
|
||||
char *n = build_nname (dir->nname, FSDB_FILE);
|
||||
unlink (n);
|
||||
free (n);
|
||||
if (!dir->nname)
|
||||
return;
|
||||
TCHAR *n = build_nname (dir->nname, FSDB_FILE);
|
||||
_wunlink (n);
|
||||
xfree (n);
|
||||
}
|
||||
|
||||
static void fsdb_fixup (FILE *f, char *buf, int size, a_inode *base)
|
||||
static void fsdb_fixup (FILE *f, TCHAR *buf, int size, a_inode *base)
|
||||
{
|
||||
char *nname;
|
||||
int ret;
|
||||
TCHAR *nname;
|
||||
int ret;
|
||||
|
||||
if (buf[0] == 0)
|
||||
return;
|
||||
nname = build_nname (base->nname, buf + 5 + 257);
|
||||
ret = fsdb_exists (nname);
|
||||
if (ret) {
|
||||
free (nname);
|
||||
return;
|
||||
}
|
||||
TRACE (("uaefsdb '%s' deleted\n", nname));
|
||||
/* someone deleted this file/dir outside of emulation.. */
|
||||
buf[0] = 0;
|
||||
free (nname);
|
||||
if (buf[0] == 0)
|
||||
return;
|
||||
nname = build_nname (base->nname, buf + 5 + 257);
|
||||
ret = fsdb_exists (nname);
|
||||
if (ret) {
|
||||
xfree (nname);
|
||||
return;
|
||||
}
|
||||
TRACE ((_T("uaefsdb '%s' deleted\n"), nname));
|
||||
/* someone deleted this file/dir outside of emulation.. */
|
||||
buf[0] = 0;
|
||||
xfree (nname);
|
||||
}
|
||||
|
||||
/* Prune the db file the first time this directory is opened in a session. */
|
||||
void fsdb_clean_dir (a_inode *dir)
|
||||
{
|
||||
char buf[1 + 4 + 257 + 257 + 81];
|
||||
char *n;
|
||||
FILE *f;
|
||||
off_t pos1 = 0, pos2;
|
||||
TCHAR buf[1 + 4 + 257 + 257 + 81];
|
||||
TCHAR *n;
|
||||
FILE *f;
|
||||
off_t pos1 = 0, pos2;
|
||||
|
||||
n = build_nname (dir->nname, FSDB_FILE);
|
||||
f = fopen (n, "r+b");
|
||||
if (f == 0) {
|
||||
free (n);
|
||||
return;
|
||||
if (!dir->nname)
|
||||
return;
|
||||
n = build_nname (dir->nname, FSDB_FILE);
|
||||
f = _tfopen (n, _T("r+b"));
|
||||
if (f == 0) {
|
||||
xfree (n);
|
||||
return;
|
||||
}
|
||||
for (;;) {
|
||||
pos2 = ftell (f);
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
break;
|
||||
fsdb_fixup (f, buf, sizeof buf, dir);
|
||||
if (buf[0] == 0)
|
||||
continue;
|
||||
if (pos1 != pos2) {
|
||||
fseek (f, pos1, SEEK_SET);
|
||||
fwrite (buf, 1, sizeof buf, f);
|
||||
fseek (f, pos2 + sizeof buf, SEEK_SET);
|
||||
}
|
||||
for (;;) {
|
||||
pos2 = ftell (f);
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
break;
|
||||
fsdb_fixup (f, buf, sizeof buf, dir);
|
||||
if (buf[0] == 0)
|
||||
continue;
|
||||
if (pos1 != pos2) {
|
||||
fseek (f, pos1, SEEK_SET);
|
||||
fwrite (buf, 1, sizeof buf, f);
|
||||
fseek (f, pos2 + sizeof buf, SEEK_SET);
|
||||
}
|
||||
pos1 += sizeof buf;
|
||||
}
|
||||
fclose (f);
|
||||
my_truncate (n, pos1);
|
||||
free (n);
|
||||
pos1 += sizeof buf;
|
||||
}
|
||||
fclose (f);
|
||||
my_truncate (n, pos1);
|
||||
xfree (n);
|
||||
}
|
||||
|
||||
static a_inode *aino_from_buf (a_inode *base, char *buf, long off)
|
||||
static a_inode *aino_from_buf (a_inode *base, uae_u8 *buf, long off)
|
||||
{
|
||||
uae_u32 mode;
|
||||
a_inode *aino = (a_inode *) xcalloc (sizeof (a_inode), 1);
|
||||
uae_u32 mode;
|
||||
a_inode *aino = xcalloc (a_inode, 1);
|
||||
|
||||
mode = do_get_mem_long ((uae_u32 *)(buf + 1));
|
||||
buf += 5;
|
||||
aino->aname = my_strdup (buf);
|
||||
buf += 257;
|
||||
aino->nname = build_nname (base->nname, buf);
|
||||
buf += 257;
|
||||
aino->comment = *buf != '\0' ? my_strdup (buf) : 0;
|
||||
fsdb_fill_file_attrs (base, aino);
|
||||
aino->amigaos_mode = mode;
|
||||
aino->has_dbentry = 1;
|
||||
aino->dirty = 0;
|
||||
aino->db_offset = off;
|
||||
return aino;
|
||||
mode = do_get_mem_long ((uae_u32 *)(buf + 1));
|
||||
buf += 5;
|
||||
aino->aname = my_strdup ((char*)buf);
|
||||
buf += 257;
|
||||
aino->nname = build_nname (base->nname, (char*)buf);
|
||||
buf += 257;
|
||||
aino->comment = *buf != '\0' ? my_strdup ((char*)buf) : 0;
|
||||
fsdb_fill_file_attrs (base, aino);
|
||||
aino->amigaos_mode = mode;
|
||||
aino->has_dbentry = 1;
|
||||
aino->dirty = 0;
|
||||
aino->db_offset = off;
|
||||
return aino;
|
||||
}
|
||||
|
||||
a_inode *fsdb_lookup_aino_aname (a_inode *base, const char *aname)
|
||||
a_inode *fsdb_lookup_aino_aname (a_inode *base, const TCHAR *aname)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
|
||||
f = get_fsdb (base, "r+b");
|
||||
if (f == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
char buf[1 + 4 + 257 + 257 + 81];
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
f = get_fsdb (base, _T("r+b"));
|
||||
if (f == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
uae_u8 buf[1 + 4 + 257 + 257 + 81];
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
break;
|
||||
if (buf[0] != 0 && same_aname (buf + 5, aname)) {
|
||||
if (buf[0] != 0 && same_aname ((char*)buf + 5, aname)) {
|
||||
long pos = ftell (f) - sizeof buf;
|
||||
fclose (f);
|
||||
return aino_from_buf (base, buf, pos);
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
a_inode *fsdb_lookup_aino_nname (a_inode *base, const char *nname)
|
||||
a_inode *fsdb_lookup_aino_nname (a_inode *base, const TCHAR *nname)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
|
||||
f = get_fsdb (base, "r+b");
|
||||
if (f == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
char buf[1 + 4 + 257 + 257 + 81];
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
f = get_fsdb (base, _T("r+b"));
|
||||
if (f == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
uae_u8 buf[1 + 4 + 257 + 257 + 81];
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
break;
|
||||
if (buf[0] != 0 && strcmp (buf + 5 + 257, nname) == 0) {
|
||||
if (buf[0] != 0 && strcmp ((char*)buf + 5 + 257, nname) == 0) {
|
||||
long pos = ftell (f) - sizeof buf;
|
||||
fclose (f);
|
||||
return aino_from_buf (base, buf, pos);
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsdb_used_as_nname (a_inode *base, const char *nname)
|
||||
int fsdb_used_as_nname (a_inode *base, const TCHAR *nname)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[1 + 4 + 257 + 257 + 81];
|
||||
FILE *f;
|
||||
uae_u8 buf[1 + 4 + 257 + 257 + 81];
|
||||
|
||||
f = get_fsdb (base, "r+b");
|
||||
if (f == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
f = get_fsdb (base, _T("r+b"));
|
||||
if (f == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (;;) {
|
||||
if (fread (buf, 1, sizeof buf, f) < sizeof buf)
|
||||
break;
|
||||
if (buf[0] == 0)
|
||||
if (buf[0] == 0)
|
||||
continue;
|
||||
if (strcmp (buf + 5 + 257, nname) == 0) {
|
||||
if (strcmp ((char*)buf + 5 + 257, nname) == 0) {
|
||||
fclose (f);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int needs_dbentry (a_inode *aino)
|
||||
{
|
||||
const char *nn_begin;
|
||||
const TCHAR *nn_begin;
|
||||
|
||||
if (aino->deleted)
|
||||
return 0;
|
||||
if (aino->deleted)
|
||||
return 0;
|
||||
|
||||
if (! fsdb_mode_representable_p (aino, aino->amigaos_mode) || aino->comment != 0)
|
||||
return 1;
|
||||
if (! fsdb_mode_representable_p (aino, aino->amigaos_mode) || aino->comment != 0)
|
||||
return 1;
|
||||
|
||||
nn_begin = nname_begin (aino->nname);
|
||||
return strcmp (nn_begin, aino->aname) != 0;
|
||||
nn_begin = nname_begin (aino->nname);
|
||||
return _tcscmp (nn_begin, aino->aname) != 0;
|
||||
}
|
||||
|
||||
static void write_aino (FILE *f, a_inode *aino)
|
||||
{
|
||||
char buf[1 + 4 + 257 + 257 + 81];
|
||||
buf[0] = aino->needs_dbentry;
|
||||
do_put_mem_long ((uae_u32 *)(buf + 1), aino->amigaos_mode);
|
||||
strncpy (buf + 5, aino->aname, 256);
|
||||
buf[5 + 256] = '\0';
|
||||
strncpy (buf + 5 + 257, nname_begin (aino->nname), 256);
|
||||
buf[5 + 257 + 256] = '\0';
|
||||
strncpy (buf + 5 + 2*257, aino->comment ? aino->comment : "", 80);
|
||||
buf[5 + 2 * 257 + 80] = '\0';
|
||||
aino->db_offset = ftell (f);
|
||||
fwrite (buf, 1, sizeof buf, f);
|
||||
aino->has_dbentry = aino->needs_dbentry;
|
||||
TRACE (("%d '%s' '%s' written\n", aino->db_offset, aino->aname, aino->nname));
|
||||
uae_u8 buf[1 + 4 + 257 + 257 + 81] = { 0 };
|
||||
buf[0] = aino->needs_dbentry;
|
||||
do_put_mem_long ((uae_u32 *)(buf + 1), aino->amigaos_mode);
|
||||
strncpy ((char*)buf + 5, aino->aname, 256);
|
||||
buf[5 + 256] = '\0';
|
||||
strncpy ((char*)buf + 5 + 257, nname_begin (aino->nname), 256);
|
||||
buf[5 + 257 + 256] = '\0';
|
||||
strncpy ((char*)buf + 5 + 2 * 257, aino->comment ? aino->comment : _T(""), 80);
|
||||
buf[5 + 2 * 257 + 80] = '\0';
|
||||
aino->db_offset = ftell (f);
|
||||
fwrite (buf, 1, sizeof buf, f);
|
||||
aino->has_dbentry = aino->needs_dbentry;
|
||||
TRACE ((_T("%d '%s' '%s' written\n"), aino->db_offset, aino->aname, aino->nname));
|
||||
}
|
||||
|
||||
/* Write back the db file for a directory. */
|
||||
|
||||
void fsdb_dir_writeback (a_inode *dir)
|
||||
{
|
||||
FILE *f;
|
||||
int changes_needed = 0;
|
||||
int entries_needed = 0;
|
||||
a_inode *aino;
|
||||
uae_u8 *tmpbuf;
|
||||
int size, i;
|
||||
FILE *f;
|
||||
int changes_needed = 0;
|
||||
int entries_needed = 0;
|
||||
a_inode *aino;
|
||||
uae_u8 *tmpbuf;
|
||||
int size, i;
|
||||
|
||||
TRACE (("fsdb writeback %s\n", dir->aname));
|
||||
/* First pass: clear dirty bits where unnecessary, and see if any work
|
||||
* needs to be done. */
|
||||
for (aino = dir->child; aino; aino = aino->sibling) {
|
||||
int old_needs_dbentry = aino->has_dbentry;
|
||||
int need = needs_dbentry (aino);
|
||||
aino->needs_dbentry = need;
|
||||
entries_needed |= need;
|
||||
if (! aino->dirty)
|
||||
TRACE ((_T("fsdb writeback %s\n"), dir->aname));
|
||||
/* First pass: clear dirty bits where unnecessary, and see if any work
|
||||
* needs to be done. */
|
||||
for (aino = dir->child; aino; aino = aino->sibling) {
|
||||
int old_needs_dbentry = aino->has_dbentry;
|
||||
int need = needs_dbentry (aino);
|
||||
aino->needs_dbentry = need;
|
||||
entries_needed |= need;
|
||||
if (! aino->dirty)
|
||||
continue;
|
||||
if (! aino->needs_dbentry && ! old_needs_dbentry)
|
||||
if (! aino->needs_dbentry && ! old_needs_dbentry)
|
||||
aino->dirty = 0;
|
||||
else
|
||||
else
|
||||
changes_needed = 1;
|
||||
}
|
||||
if (! entries_needed) {
|
||||
kill_fsdb (dir);
|
||||
TRACE (("fsdb removed\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (! entries_needed) {
|
||||
kill_fsdb (dir);
|
||||
TRACE ((_T("fsdb removed\n")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (! changes_needed) {
|
||||
TRACE (("not modified\n"));
|
||||
return;
|
||||
}
|
||||
if (! changes_needed) {
|
||||
TRACE ((_T("not modified\n")));
|
||||
return;
|
||||
}
|
||||
|
||||
f = get_fsdb (dir, "r+b");
|
||||
if (f == 0) {
|
||||
f = get_fsdb (dir, "w+b");
|
||||
if (f == 0) {
|
||||
TRACE (("failed\n"));
|
||||
f = get_fsdb (dir, _T("r+b"));
|
||||
if (f == 0) {
|
||||
f = get_fsdb (dir, _T("w+b"));
|
||||
if (f == 0) {
|
||||
TRACE ((_T("failed\n")));
|
||||
/* This shouldn't happen... */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
fseek (f, 0, SEEK_END);
|
||||
size = ftell (f);
|
||||
fseek (f, 0, SEEK_SET);
|
||||
tmpbuf = 0;
|
||||
if (size > 0) {
|
||||
tmpbuf = (uae_u8 *)malloc (size);
|
||||
fread (tmpbuf, 1, size, f);
|
||||
}
|
||||
TRACE (("**** updating '%s' %d\n", dir->aname, size));
|
||||
fseek (f, 0, SEEK_END);
|
||||
size = ftell (f);
|
||||
fseek (f, 0, SEEK_SET);
|
||||
tmpbuf = 0;
|
||||
if (size > 0) {
|
||||
tmpbuf = (uae_u8 *)malloc (size);
|
||||
fread (tmpbuf, 1, size, f);
|
||||
}
|
||||
TRACE ((_T("**** updating '%s' %d\n"), dir->aname, size));
|
||||
|
||||
for (aino = dir->child; aino; aino = aino->sibling) {
|
||||
|
||||
if (! aino->dirty)
|
||||
for (aino = dir->child; aino; aino = aino->sibling) {
|
||||
if (! aino->dirty)
|
||||
continue;
|
||||
aino->dirty = 0;
|
||||
aino->dirty = 0;
|
||||
|
||||
i = 0;
|
||||
while (!aino->has_dbentry && i < size) {
|
||||
i = 0;
|
||||
while (!aino->has_dbentry && i < size) {
|
||||
if (!strcmp ((const char *)(tmpbuf + i + 5), aino->aname)) {
|
||||
aino->has_dbentry = 1;
|
||||
aino->db_offset = i;
|
||||
aino->has_dbentry = 1;
|
||||
aino->db_offset = i;
|
||||
}
|
||||
i += 1 + 4 + 257 + 257 + 81;
|
||||
}
|
||||
if (! aino->has_dbentry) {
|
||||
}
|
||||
if (! aino->has_dbentry) {
|
||||
fseek (f, 0, SEEK_END);
|
||||
aino->has_dbentry = 1;
|
||||
} else {
|
||||
} else {
|
||||
fseek (f, aino->db_offset, SEEK_SET);
|
||||
}
|
||||
write_aino (f, aino);
|
||||
}
|
||||
TRACE (("end\n"));
|
||||
fclose (f);
|
||||
free (tmpbuf);
|
||||
write_aino (f, aino);
|
||||
}
|
||||
TRACE ((_T("end\n")));
|
||||
fclose (f);
|
||||
xfree (tmpbuf);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue