#include <dataworks.h>
+#include <dw_database.h>
#include <dw_util.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
extern int argc;
extern char** argv;
#include <bios.h>
+#include <i86.h>
+#include <conio.h>
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) {
}
}
+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;
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 {
}
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");
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;
+}
#include <dataworks.h>
+#include <dw_database.h>
#include <dw_util.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
int argc;
char** argv;
-
#ifdef __DOS__
-#include <bios.h>
-
-/* Why would you run the database server on DOS, tho ... */
-#define HAYES
-#else
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#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) {
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();
}
#include <dataworks.h>
+#include <dw_database.h>
#include <dw_util.h>
#include <stdbool.h>
#include <unistd.h>
void protocol_init(int sock);
+void protocol_loop(int sock);
bool option(const char* str, const char* shortopt, const char* longopt);
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;
i++;
port = atoi(argv[i]);
}
+ }else{
+ db = dataworks_database_open(argv[i]);
}
}
if((server_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) {
pid_t p = fork();
if(p == 0) {
protocol_init(sock);
+ protocol_loop(sock);
_exit(0);
} else {
close(sock);
}
}
+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);
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