--- uae/src/filesys.c 2018/04/24 16:38:39 1.1 +++ uae/src/filesys.c 2018/04/24 16:39:17 1.1.1.2 @@ -32,12 +32,13 @@ #include "memory.h" #include "custom.h" #include "events.h" +#include "readcpu.h" #include "newcpu.h" #include "xwin.h" #include "autoconf.h" #include "compiler.h" -#ifdef __bebox__ +#ifdef __BEOS__ #undef access // This is just a temporary hack. // (Will be obsolete in future versions of the BeOS) [ So I hope -- Bernd ] @@ -95,6 +96,46 @@ void add_filesys_unit(char *volname, cha num_units++; } +int kill_filesys_unit(char *volname) +{ + size_t l = strlen(volname); + int i; + + if (l == 0) + return -1; + + if (volname[l-1] == ':') + l--; + + for (i = 0; i < num_units; i++) { + if (ui[i].volname != NULL + && strlen(ui[i].volname) == l + && strncmp(ui[i].volname, volname, l) == 0) + break; + } + if (i == num_units) + return -1; + + num_units--; + for (; i < num_units; i++) { + ui[i] = ui[i+1]; + } + return 0; +} + +int sprintf_filesys_unit(char *buffer, int num) +{ + if (num >= num_units) + return -1; + if (ui[num].volname != NULL) + sprintf(buffer, "%s: %s %s", ui[num].volname, ui[num].rootdir, + ui[num].readonly ? "ro" : ""); + else + sprintf(buffer, "Hardfile \"UAE0:\", size %d bytes", + hardfile_size); + return 0; +} + void write_filesys_config(FILE *f) { int i; @@ -105,7 +146,7 @@ void write_filesys_config(FILE *f) } } } - +/*#define TRACING_ENABLED*/ #ifdef TRACING_ENABLED #define TRACE(x) printf x; #define DUMPLOCK(x) dumplock(x) @@ -218,19 +259,19 @@ typedef struct _unit { CPTR port; /* Our port */ /* Native stuff */ - long unit; /* unit number */ + LONG unit; /* unit number */ UnitInfo ui; /* unit startup info */ } Unit; typedef struct { CPTR addr; /* addr of real packet */ - long type; - long res1; - long res2; - long arg1; - long arg2; - long arg3; - long arg4; + LONG type; + LONG res1; + LONG res2; + LONG arg1; + LONG arg2; + LONG arg3; + LONG arg4; } DosPacket; static char * @@ -264,9 +305,9 @@ static CPTR DosAllocMem(ULONG len) ULONG i; CPTR addr; - regs.d[0] = len + 4; - regs.d[1] = 1; /* MEMF_PUBLIC */ - addr = CallLib(regs.a[6], -198); /* AllocMem */ + m68k_dreg(regs, 0) = len + 4; + m68k_dreg(regs, 1) = 1; /* MEMF_PUBLIC */ + addr = CallLib(m68k_areg(regs, 6), -198); /* AllocMem */ if(addr) { put_long(addr, len); @@ -283,9 +324,9 @@ static CPTR DosAllocMem(ULONG len) static void DosFreeMem(CPTR addr) { addr -= 4; - regs.d[0] = get_long(addr) + 4; - regs.a[1] = addr; - CallLib(regs.a[6], -210); /* FreeMem */ + m68k_dreg(regs, 0) = get_long(addr) + 4; + m68k_areg(regs, 1) = addr; + CallLib(m68k_areg(regs, 6), -210); /* FreeMem */ } static void @@ -321,7 +362,7 @@ startup(DosPacket* packet) units = unit; unit->volume = 0; - unit->port = regs.a[5]; + unit->port = m68k_areg(regs, 5); unit->unit = unit_num++; unit->ui.devname = ui[i].devname; @@ -335,9 +376,9 @@ startup(DosPacket* packet) put_long((packet->arg3 << 2) + 8, unit->port); /* open dos.library */ - regs.d[0] = 0; - regs.a[1] = EXPANSION_doslibname; - unit->dosbase = CallLib(regs.a[6], -552); /* OpenLibrary */ + m68k_dreg(regs, 0) = 0; + m68k_areg(regs, 1) = EXPANSION_doslibname; + unit->dosbase = CallLib(m68k_areg(regs, 6), -552); /* OpenLibrary */ { CPTR rootnode = get_long(unit->dosbase + 34); @@ -923,7 +964,7 @@ action_examine_next(Unit* unit, DosPacke } static void -do_find(Unit* unit, DosPacket* packet, mode_t mode) +do_find(Unit* unit, DosPacket* packet, mode_t mode, int fallback) { CPTR fh = packet->arg1 << 2; CPTR lock = packet->arg2 << 2; @@ -952,7 +993,20 @@ do_find(Unit* unit, DosPacket* packet, m k->fd = open(k->path, mode | O_BINARY, 0777); - if(k->fd < 0) { + if (k->fd < 0 + && (errno == EACCES +#if defined(EROFS) + || errno == EROFS +#endif + ) + && fallback) + { + mode &= ~O_RDWR; + mode |= O_RDONLY; + k->fd = open(k->path, mode | O_BINARY, 0777); + } + + if (k->fd < 0) { packet->res1 = DOS_FALSE; packet->res2 = dos_errno(); free_key(k); @@ -967,7 +1021,11 @@ do_find(Unit* unit, DosPacket* packet, m static void action_find_input(Unit* unit, DosPacket* packet) { - do_find(unit, packet, O_RDWR); + if(unit->ui.readonly) { + do_find(unit, packet, O_RDONLY, 0); + } else { + do_find(unit, packet, O_RDWR, 1); + } } static void @@ -978,7 +1036,7 @@ action_find_output(Unit* unit, DosPacket packet->res2 = ERROR_DISK_WRITE_PROTECTED; return; } - do_find(unit, packet, O_RDWR|O_CREAT|O_TRUNC); + do_find(unit, packet, O_RDWR|O_CREAT|O_TRUNC, 0); } static void @@ -989,7 +1047,7 @@ action_find_write(Unit* unit, DosPacket* packet->res2 = ERROR_DISK_WRITE_PROTECTED; return; } - do_find(unit, packet, O_RDWR); + do_find(unit, packet, O_RDWR, 0); } static void @@ -1001,6 +1059,7 @@ action_end(Unit* unit, DosPacket* packet k = lookup_key(packet->arg1); free_key(k); packet->res1 = DOS_TRUE; + packet->res2 = 0; } static void @@ -1029,7 +1088,10 @@ action_read(Unit* unit, DosPacket* packe realpt = get_real_address (addr); actual = read(k->fd, realpt, size); - if (actual <= 0) { + if (actual == 0) { + packet->res1 = 0; + packet->res2 = 0; + } else if (actual < 0) { packet->res1 = 0; packet->res2 = dos_errno(); } else { @@ -1038,7 +1100,7 @@ action_read(Unit* unit, DosPacket* packe } } else { char *buf; - fprintf (stderr, "unixfs warning: Bad pointer passed for read\n"); + fprintf (stderr, "unixfs warning: Bad pointer passed for read: %08x\n", addr); /* ugh this is inefficient but easy */ buf = (char *)malloc(size); if(!buf) { @@ -1048,7 +1110,7 @@ action_read(Unit* unit, DosPacket* packe } actual = read(k->fd, buf, size); - if (actual <= 0) { + if (actual < 0) { packet->res1 = 0; packet->res2 = dos_errno(); } else { @@ -1156,23 +1218,27 @@ action_set_protect(Unit* unit, DosPacket } mode = statbuf.st_mode; - - if(mask & (1 << 3)) +#ifdef __unix /* Unix dirs behave differently than AmigaOS ones. */ + if (S_ISDIR (mode)) { + mask &= ~15; + } +#endif + if (mask & (1 << 3)) mode &= ~S_IRUSR; else mode |= S_IRUSR; - if(mask & (1 << 2) || mask & (1 << 0)) + if (mask & (1 << 2) || mask & (1 << 0)) mode &= ~S_IWUSR; else mode |= S_IWUSR; - if(mask & (1 << 1)) + if (mask & (1 << 1)) mode &= ~S_IXUSR; else mode |= S_IXUSR; - if(-1 == chmod(k->path, mode)) { + if (-1 == chmod(k->path, mode)) { packet->res1 = DOS_FALSE; packet->res2 = dos_errno(); } else { @@ -1256,12 +1322,7 @@ action_create_dir(Unit* unit, DosPacket* packet->res2 = ERROR_NO_FREE_STORE; return; } -#ifndef AMIGA - if(-1 == mkdir(k->path, 0777)) -#else - if(-1 == mkdir(k->path)) -#endif - { + if(-1 == mkdir(k->path, 0777)) { packet->res1 = DOS_FALSE; packet->res2 = dos_errno(); free_key(k); @@ -1325,9 +1386,7 @@ action_set_date(Unit* unit, DosPacket* p CPTR name = packet->arg3 << 2; CPTR date = packet->arg4; Key* k; -#if !defined(AMIGA) struct utimbuf ut; -#endif TRACE(("ACTION_SET_DATE(0x%lx,\"%s\")\n",lock,bstr(name))); @@ -1337,9 +1396,7 @@ action_set_date(Unit* unit, DosPacket* p return; } -#if !defined(AMIGA) ut.actime = ut.modtime = put_time(get_long(date),get_long(date+4),get_long(date+8)); -#endif k = make_key(unit, lock, bstr(name)); if(!k) { @@ -1347,14 +1404,12 @@ action_set_date(Unit* unit, DosPacket* p packet->res2 = ERROR_NO_FREE_STORE; return; } -#if !defined(AMIGA) if(-1 == utime(k->path, &ut)) { packet->res1 = DOS_FALSE; packet->res2 = dos_errno(); free_key(k); return; } -#endif free_key(k); packet->res1 = DOS_TRUE; } @@ -1457,10 +1512,10 @@ static ULONG filesys_handler(void) { DosPacket packet; - Unit *unit = find_unit(regs.a[5]); + Unit *unit = find_unit(m68k_areg(regs, 5)); /* got DosPacket in A4 */ - packet.addr = regs.a[4]; + packet.addr = m68k_areg(regs, 4); packet.type = get_long(packet.addr + dp_Type); packet.res1 = get_long(packet.addr + dp_Res1); packet.res2 = get_long(packet.addr + dp_Res2); @@ -1598,9 +1653,9 @@ filesys_handler(void) static ULONG filesys_diagentry(void) { - CPTR resaddr = regs.a[2] + 0x10; + CPTR resaddr = m68k_areg(regs, 2) + 0x10; - filesys_configdev = regs.a[3]; + filesys_configdev = m68k_areg(regs, 3); if (ROM_hardfile_resid != 0) { /* Build a struct Resident. This will set up and initialize @@ -1616,6 +1671,10 @@ static ULONG filesys_diagentry(void) } resaddr += 0x1A; + /* The good thing about this function is that it always gets called + * when we boot. So we could put all sorts of stuff that wants to be done + * here. */ + return 1; } @@ -1623,7 +1682,7 @@ static CPTR build_parmpacket(void) { CPTR tmp1; - regs.d[0] = 88; regs.d[1] = 1; /* MEMF_PUBLIC */ + m68k_dreg(regs, 0) = 88; m68k_dreg(regs, 1) = 1; /* MEMF_PUBLIC */ tmp1 = CallLib (get_long(4), -198); /* AllocMem() */ if (tmp1 == 0) { fprintf(stderr, "Not enough memory for filesystem!\n"); @@ -1641,14 +1700,10 @@ static CPTR build_parmpacket(void) put_long (tmp1+44, 0); /* unused */ put_long (tmp1+48, 0); /* interleave */ put_long (tmp1+52, 0); /* lowCyl */ -#ifndef __DOS__ - put_long (tmp1+56, 511); /* upperCyl */ -#else { extern int numtracks; put_long (tmp1+56, numtracks-1); /* upperCyl */ } -#endif put_long (tmp1+60, 0); /* Number of buffers */ put_long (tmp1+64, 0); /* Buffer mem type */ put_long (tmp1+68, 0x7FFFFFFF); /* largest transfer */ @@ -1673,7 +1728,7 @@ static void make_dev(CPTR param_packet, put_long (param_packet + 4, is_hardfile ? ROM_hardfile_resname : fsdevname); put_long (param_packet + 8, ui[unit_no].devno); - regs.a[0] = param_packet; + m68k_areg(regs, 0) = param_packet; devicenode = CallLib (EXPANSION_explibbase, -144); /* MakeDosNode() */ ui[unit_no].startup = get_long(devicenode + 28); if (!is_hardfile) { @@ -1691,14 +1746,14 @@ static void make_dev(CPTR param_packet, if (boot) { if (EXPANSION_haveV36) { - regs.d[0] = -1; regs.d[1] = 0; - regs.a[0] = devicenode; - regs.a[1] = filesys_configdev; + m68k_dreg(regs, 0) = -1; m68k_dreg(regs, 1) = 0; + m68k_areg(regs, 0) = devicenode; + m68k_areg(regs, 1) = filesys_configdev; CallLib(EXPANSION_explibbase, -36); } else { /* Construct a BootNode and Enqueue() it into eb_MountList */ - regs.d[0] = 20; - regs.d[1] = 0; + m68k_dreg(regs, 0) = 20; + m68k_dreg(regs, 1) = 0; bootnode = CallLib (get_long(4), -198); /* AllocMem() */ put_word (bootnode + 14, 0); /* Flags (??) */ @@ -1707,16 +1762,16 @@ static void make_dev(CPTR param_packet, put_long (bootnode + 10, filesys_configdev); /* Name */ put_long (bootnode + 0, 0); put_long (bootnode + 4, 0); - regs.a[0] = EXPANSION_explibbase + 74; /* MountList */ - regs.a[1] = bootnode; + m68k_areg(regs, 0) = EXPANSION_explibbase + 74; /* MountList */ + m68k_areg(regs, 1) = bootnode; CallLib (get_long(4), -270); /* Enqueue() */ } } else { /* Call AddDosNode() for the constructed node */ - regs.a[0] = devicenode; - regs.d[0] = (ULONG)-1; - regs.a[1] = 0; - regs.d[1] = 0; /* Flags */ + m68k_areg(regs, 0) = devicenode; + m68k_dreg(regs, 0) = (ULONG)-1; + m68k_areg(regs, 1) = 0; + m68k_dreg(regs, 1) = 0; /* Flags */ CallLib (EXPANSION_explibbase, -150); /* AddDosNode() */ } } @@ -1729,14 +1784,14 @@ void filesys_init(void) /* Open expansion.lib */ EXPANSION_haveV36 = 0; - regs.d[0] = 36; - regs.a[1] = EXPANSION_explibname; + m68k_dreg(regs, 0) = 36; + m68k_areg(regs, 1) = EXPANSION_explibname; EXPANSION_explibbase = CallLib (get_long(4), -552); /* OpenLibrary() */ if (EXPANSION_explibbase) EXPANSION_haveV36 = 1; else { - regs.d[0] = 0; - regs.a[1] = EXPANSION_explibname; + m68k_dreg(regs, 0) = 0; + m68k_areg(regs, 1) = EXPANSION_explibname; EXPANSION_explibbase = CallLib (get_long(4), -552); /* OpenLibrary() */ } @@ -1755,7 +1810,7 @@ void filesys_init(void) make_dev(filesys_parampacket, i, is_hardfile, 1); } - regs.a[1] = EXPANSION_explibbase; + m68k_areg(regs, 1) = EXPANSION_explibbase; CallLib (get_long(4), -414); /* CloseLibrary() */ EXPANSION_explibbase = 0; }