From fad8082be246bea6908e86929bfd314298064ffa Mon Sep 17 00:00:00 2001 From: nishi Date: Wed, 5 Jun 2024 13:00:48 +0000 Subject: [PATCH] will add pc-98 support when dosbox-x adds modem support for it git-svn-id: file:///raid/svn-main/nishi-dataworks/trunk@162 d4a5a174-5a4a-5b4b-b672-37683c10d7d5 --- Server/hayes.c | 75 +++++++++++++++++++++++++++++++---- Server/server.c | 101 ++++++++++++++++++++++++++++++++++++++++-------- Server/tcpip.c | 32 +++++++++++++++ common.mk | 2 +- 4 files changed, 185 insertions(+), 25 deletions(-) diff --git a/Server/hayes.c b/Server/hayes.c index decd50b..a70c4a2 100644 --- a/Server/hayes.c +++ b/Server/hayes.c @@ -28,24 +28,47 @@ #include +#include #include #include #include #include #include +#include extern int argc; extern char** argv; #include +#include +#include void protocol_init(int sock); +void protocol_loop(int sock); +void disconnect(int sock); bool option(const char* str, const char* shortopt, const char* longopt); int port = -1; +int get_ioport(){ +#ifdef PC98 + if(port == 0) return 0x30; +#else + if(port == 0){ + return 0x3f8; + }else if(port == 1){ + return 0x2f8; + }else if(port == 2){ + return 0x3e8; + }else if(port == 3){ + return 0x2e8; + } +#endif + return 0; +} + void write_serial(const char* str) { const char* ptr = str; while(1) { @@ -57,41 +80,59 @@ void write_serial(const char* str) { } } +bool connected; + +extern sig_atomic_t signals; +extern struct dataworks_db* db; + char* modem_response(void) { - char* buf = malloc(513); + char* buf = malloc(1); buf[0] = 0; - int count = 0; + char cbuf[2]; + cbuf[1] = 0; while(1) { if(_bios_serialcom(_COM_STATUS, port, 0) & 0x0100) { unsigned short b = _bios_serialcom(_COM_RECEIVE, port, 0); char ch = b & 0xff; if(ch != '\r' && ch != '\n' && ch != 0) { - buf[count] = ch; - buf[count + 1] = 0; - count++; + cbuf[0] = ch; + char* tmp = buf; + buf = __dw_strcat(tmp, cbuf); + free(tmp); } else if(ch == '\r') { if(strlen(buf) != 0) break; } } + printf("\r"); + if(signals > 0){ + free(buf); + if(connected){ + disconnect(0); + } + return NULL; + } } return buf; } int server_init(void) { printf("Using Hayes Modem\n"); + connected = false; int i; for(i = 1; i < argc; i++) { if(argv[i][0] == '/' || argv[i][0] == '-'){ if(option(argv[i], "p", "port")){ i++; if(__dw_strcaseequ(argv[i], "COM1")) { - port = 0; + port = 0; +#ifndef PC98 } else if(__dw_strcaseequ(argv[i], "COM2")) { port = 1; } else if(__dw_strcaseequ(argv[i], "COM3")) { port = 2; } else if(__dw_strcaseequ(argv[i], "COM4")) { port = 3; +#endif } else { fprintf(stderr, "Invalid port: %s\n", argv[i]); return 1; @@ -100,16 +141,23 @@ int server_init(void) { fprintf(stderr, "Invalid option: %s\n", argv[i]); return 1; } + }else{ + db = dataworks_database_open(argv[i]); } } if(port == -1) { fprintf(stderr, "Specify serial port\n"); return 1; } + printf("Serial port is at I/O 0x%4.4x\n", get_ioport()); _bios_serialcom(_COM_INIT, port, _COM_9600 | _COM_NOPARITY | _COM_CHR8 | _COM_STOP1); write_serial("AT&FE0F1\r"); - free(modem_response()); /* Kill echo */ char* resp = modem_response(); + bool echo = __dw_strcaseequ(resp, "AT&FE0F1"); + if(resp != NULL && echo) free(resp); /* Kill echo */ + if(resp == NULL) return 0; + if(echo) resp = modem_response(); + if(resp == NULL) return 0; if(__dw_strcaseequ(resp, "OK")) { fprintf(stderr, "Modem initialization successful\n"); } else { @@ -122,9 +170,10 @@ int server_init(void) { } void server_loop(void) { - bool connected = false; + connected = false; while(1) { char* resp = modem_response(); + if(resp == NULL) break; if(__dw_strcaseequ(resp, "NO CARRIER")) { free(resp); printf("Disconnected\n"); @@ -152,14 +201,24 @@ void server_loop(void) { printf("Entering connected state\n"); connected = true; protocol_init(0); + protocol_loop(0); } } free(resp); } } +char* readline_sock(int sock){ + return connected ? modem_response() : NULL; +} + void writeline(int sock, const char* str) { char* snd = __dw_strcat(str, "\r\n"); write_serial(snd); free(snd); } + +void disconnect(int sock){ + while(inp(get_ioport() + 6) & (1 << 7)) outp(get_ioport() + 4, 0); + connected = false; +} diff --git a/Server/server.c b/Server/server.c index 8299d6d..35c2160 100644 --- a/Server/server.c +++ b/Server/server.c @@ -28,32 +28,23 @@ #include +#include #include #include #include #include #include +#include int argc; char** argv; - #ifdef __DOS__ -#include - -/* Why would you run the database server on DOS, tho ... */ -#define HAYES -#else -#include -#include -#include -#include -#include -#include - -#define TCPIP +sig_atomic_t signals = 0; #endif +struct dataworks_db* db = NULL; + void protocol_init(int sock); bool option(const char* str, const char* shortopt, const char* longopt) { @@ -68,19 +59,97 @@ bool option(const char* str, const char* shortopt, const char* longopt) { int server_init(void); void server_loop(void); void writeline(int sock, const char* str); +char* readline_sock(int sock); +void disconnect(int sock); void protocol_init(int sock) { /* sock is ignored on hayes */ - char* verstr = __dw_strcat("READY:VER=", dataworks_get_version()); + writeline(sock, "READY"); + char* tmp; + char* verstr; + verstr = __dw_strcat("ATTR:AUTH:VER=", dataworks_get_version()); + + tmp = verstr; + verstr = __dw_strcat(tmp, ":PLATFORM="); + free(tmp); + + tmp = verstr; + verstr = __dw_strcat(tmp, dataworks_get_platform()); + free(tmp); + writeline(sock, verstr); - writeline(sock, "ATTR:AUTH=YES"); + free(verstr); } +void protocol_loop(int sock){ + while(1){ + char* buf = readline_sock(sock); + if(buf == NULL){ + break; + } + int i; + bool has_arg = false; + for(i = 0; buf[i] != 0; i++){ + if(buf[i] == ':'){ + buf[i] = 0; + has_arg = true; + break; + } + } + if(__dw_strcaseequ(buf, "ECHO")){ + int start; + if(has_arg){ + i++; + start = i; + for(;; i++){ + if(buf[i] == ':' || buf[i] == 0){ + char oldc = buf[i]; + buf[i] = 0; + char* echo = __dw_strcat("ECHO:", buf + start); + start = i + 1; + + writeline(sock, echo); + free(echo); + if(oldc == 0) break; + } + } + }else{ + writeline(sock, "ECHO"); + } + }else if(__dw_strcaseequ(buf, "BYE") || __dw_strcaseequ(buf, "QUIT")){ + writeline(sock, "QUIT:Bye"); + disconnect(sock); + }else{ + writeline(sock, "ERROR:UNKNOWN_CMD"); + } + free(buf); + } +} + +#ifdef __DOS__ +void exitnow(int sig){ + signals++; +} +#endif + int main(int _argc, char** _argv) { argc = _argc; argv = _argv; +#ifdef __DOS__ + signal(SIGINT, exitnow); +#endif printf("DataWorks Server version %s %s %s\n", dataworks_get_version(), dataworks_get_compile_date(), dataworks_get_platform()); int st; if((st = server_init()) != 0) return st; + if(db != NULL){ + if(db->error){ + dataworks_database_close(db); + db = NULL; + } + } + if(db == NULL){ + fprintf(stderr, "Failed to open databse\n"); + return 1; + } server_loop(); } diff --git a/Server/tcpip.c b/Server/tcpip.c index 013a843..923ad0c 100644 --- a/Server/tcpip.c +++ b/Server/tcpip.c @@ -28,6 +28,7 @@ #include +#include #include #include @@ -46,6 +47,7 @@ extern char** argv; #include void protocol_init(int sock); +void protocol_loop(int sock); bool option(const char* str, const char* shortopt, const char* longopt); @@ -53,6 +55,8 @@ int port = 4096; int server_socket; struct sockaddr_in6 server_address; +extern struct dataworks_db* db; + int server_init(void) { printf("Using BSD TCP/IP\n"); int i; @@ -62,6 +66,8 @@ int server_init(void) { i++; port = atoi(argv[i]); } + }else{ + db = dataworks_database_open(argv[i]); } } if((server_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) { @@ -112,6 +118,7 @@ void server_loop(void) { pid_t p = fork(); if(p == 0) { protocol_init(sock); + protocol_loop(sock); _exit(0); } else { close(sock); @@ -119,6 +126,31 @@ void server_loop(void) { } } +char* readline_sock(int sock){ + char cbuf[2]; + cbuf[1] = 0; + char* buf = malloc(1); + buf[0] = 0; + while(1){ + int l = recv(sock, cbuf, 1, 0); + if(l <= 0){ + free(buf); + return NULL; + }else if(cbuf[0] == '\n'){ + break; + }else if(cbuf[0] != '\r'){ + char* tmp = buf; + buf = __dw_strcat(tmp, cbuf); + free(tmp); + } + } + return buf; +} + +void disconnect(int sock){ + close(sock); +} + void writeline(int sock, const char* str) { char* snd = __dw_strcat(str, "\r\n"); send(sock, snd, strlen(snd), 0); diff --git a/common.mk b/common.mk index a7c8000..c0d1fdf 100644 --- a/common.mk +++ b/common.mk @@ -95,7 +95,7 @@ prepare-dosbox: no-doc echo "c:" >> dosbox.conf echo "copy Server\*$(EXEC_SUFFIX) dwserv$(EXEC_SUFFIX)" >> dosbox.conf echo "copy Client\*$(EXEC_SUFFIX) dw$(EXEC_SUFFIX)" >> dosbox.conf - echo "dwserv -p COM1" >> dosbox.conf + echo "dwserv -p COM1 db.dwf" >> dosbox.conf echo "dw /NC /f op.txt /create db.dwf" >> dosbox.conf echo "dw /NC /f op.txt db.dwf" >> dosbox.conf echo "pause" >> dosbox.conf -- 2.43.0