From d718d82ff141698e0f92e0816f4ed14e04b53e15 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 10 Aug 2018 17:53:09 -0500 Subject: [PATCH] Initial support for mounting and reading a remote filesystem. --- Makefile | 8 +++++- driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- driver.h | 3 ++ mounturl.c | 19 +++++++++++++ session.h | 3 ++ 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 mounturl.c diff --git a/Makefile b/Makefile index ac994ee..089649d 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,9 @@ CFLAGS = -w-1 -O-1 HTTPTEST_OBJS = httptest.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a HTTPTEST_PROG = httptest +MOUNTURL_OBJS = mounturl.a +MOUNTURL_PROG = mounturl + NETDISKINIT_OBJS = initstart.a netdiskinit.a hostname.a http.a readtcp.a seturl.a strcasecmp.a tcpconnection.a urlparser.a driver.a installdriver.a asmglue.a driverwrapper.a # NETDISKINIT_RSRC = NETDISKINIT_PROG = NetDiskInit @@ -14,7 +17,7 @@ NETDISKINIT_PROG = NetDiskInit MACROS = asmglue.macros -PROGS = $(HTTPTEST_PROG) $(NETDISKINIT_PROG) +PROGS = $(HTTPTEST_PROG) $(NETDISKINIT_PROG) $(MOUNTURL_PROG) .PHONY: default default: $(PROGS) @@ -22,6 +25,9 @@ default: $(PROGS) $(HTTPTEST_PROG): $(HTTPTEST_OBJS) $(CC) $(CFLAGS) -o $@ $^ +$(MOUNTURL_PROG): $(MOUNTURL_OBJS) + $(CC) $(CFLAGS) -o $@ $^ + $(NETDISKINIT_PROG): $(NETDISKINIT_OBJS) $(CC) $(CFLAGS) -o $@ $^ iix chtyp -tpif $@ diff --git a/driver.c b/driver.c index 14be816..79e11ab 100644 --- a/driver.c +++ b/driver.c @@ -3,6 +3,10 @@ #include #include "driver.h" #include "driverwrapper.h" +#include "session.h" +#include "seturl.h" +#include "http.h" +#include "readtcp.h" #include "version.h" struct DIB dibs[NDIBS] = {0}; @@ -10,6 +14,7 @@ struct DIBList dibList = {NDIBS}; struct GSOSDP *gsosDP = (void*)0x00BD00; /* GS/OS direct page ptr */ +static Word DoMountURL(struct GSOSDP *dp); static Word DoRead(struct GSOSDP *dp); static Word DoStatus(struct GSOSDP *dp); static Word DoEject(struct GSOSDP *dp); @@ -152,6 +157,10 @@ Word DriverDispatch(Word callNum, struct GSOSDP *dp) { dp->transferCount = 0; break; + case Mount_URL: + DoMountURL(dp); + break; + default: dp->transferCount = 0; retVal = drvrBadCode; @@ -178,8 +187,73 @@ Word DriverDispatch(Word callNum, struct GSOSDP *dp) { #pragma databank 0 +static Word DoMountURL(struct GSOSDP *dp) { + if (dp->dibPointer->extendedDIBPtr != NULL) { + dp->transferCount = 0; + return drvrBusy; + } + + Session *sess = calloc(sizeof(*sess), 1); + if (sess == NULL) { + dp->transferCount = 0; + return drvrNoResrc; + } + dp->dibPointer->extendedDIBPtr = sess; + + enum SetURLResult setResult = SetURL(sess, (char*)dp->controlListPtr, TRUE, FALSE); + if (setResult != SETURL_SUCCESSFUL) { + // TODO arrange for more detailed error reporting + dp->transferCount = 0; + return drvrIOError; + } + + enum RequestResult requestResult = DoHTTPRequest(sess, 0, sizeof(sess->fileHeaderBuf) - 1); + if (requestResult != REQUEST_SUCCESSFUL) { + // TODO arrange for more detailed error reporting + dp->transferCount = 0; + return drvrIOError; + } + + InitReadTCP(sess, sizeof(sess->fileHeaderBuf), &sess->fileHeaderBuf); + while (TryReadTCP(sess) == rsWaiting) + // TODO timeout + /* keep reading */ ; + //TODO detect errors + + //TODO detect 2mg + + //TODO report disk switch + + return 0; +} + static Word DoRead(struct GSOSDP *dp) { - //TODO + Session *sess = dp->dibPointer->extendedDIBPtr; + if (sess == NULL) { + dp->transferCount = 0; + return drvrOffLine; + } + + //TODO check size is multiple of a block + //TODO disk-switched logic + + unsigned long readStart = dp->blockNum * dp->blockSize; + unsigned long readEnd = readStart + dp->requestCount - 1; + + enum RequestResult requestResult = DoHTTPRequest(sess, readStart, readEnd); + if (requestResult != REQUEST_SUCCESSFUL) { + // TODO arrange for more detailed error reporting + dp->transferCount = 0; + return drvrIOError; + } + + InitReadTCP(sess, dp->requestCount, dp->bufferPtr); + while (TryReadTCP(sess) == rsWaiting) + // TODO timeout + /* keep reading */ ; + //TODO detect errors + + dp->transferCount = dp->requestCount - sess->readCount; return 0; } @@ -190,7 +264,11 @@ static Word DoStatus(struct GSOSDP *dp) { } //TODO handle actual disk, and disk-switched logic /* no disk in drive, ... */ - ((DeviceStatusRec*)dp->statusListPtr)->statusWord = 0; + if (dp->dibPointer->extendedDIBPtr != NULL) { + ((DeviceStatusRec*)dp->statusListPtr)->statusWord = 0x8014; + } else { + ((DeviceStatusRec*)dp->statusListPtr)->statusWord = 0; + } if (dp->requestCount < 6) { dp->transferCount = 2; return 0; diff --git a/driver.h b/driver.h index 827eb37..4e21702 100644 --- a/driver.h +++ b/driver.h @@ -68,6 +68,9 @@ struct GSOSDP { #define Get_Format_Options 0x0003 #define Get_Partition_Map 0x0004 +/* Custom Driver_Control subcall */ +#define Mount_URL 0x8080 + /* Status list record for Get_DeviceStatus */ typedef struct DeviceStatusRec { Word statusWord; diff --git a/mounturl.c b/mounturl.c new file mode 100644 index 0000000..d8da55e --- /dev/null +++ b/mounturl.c @@ -0,0 +1,19 @@ +#include +#include +#include + +#define MountURL 0x8080 + +int main(int argc, char **argv) { + DAccessRecGS controlRec = {5}; + + if (argc < 3) + return; + + controlRec.devNum = strtoul(argv[1], NULL, 0); + controlRec.code = MountURL; + controlRec.list = argv[2]; + controlRec.requestCount = strlen(argv[2]) + 1; + + DControl(&controlRec); +} diff --git a/session.h b/session.h index 5e980bc..40cc95d 100644 --- a/session.h +++ b/session.h @@ -47,6 +47,9 @@ typedef struct Session { LongWord desiredStart, desiredEnd; /* Expected length of disk image */ LongWord expectedLength; + + /* Buffer for initial bytes of file (which may be a disk image header) */ + unsigned char fileHeaderBuf[32]; } Session; #endif