Browse Source

Added MagiDoor to project

  Go bugz go!
david 4 years ago
parent
commit
07d884fdbe

+ 0 - 1
.gitignore

@@ -1,5 +1,4 @@
 build/
 example-sqlite3/
-MagiDoor/
 logs/
 spaceconstruct.db3

+ 7 - 0
MagiDoor/CMakeLists.txt

@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.6)
+project(magidoor)
+
+set(HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(SOURCE_FILES MD_Sendfile.c MD_Getc.c MD_Printf.c MD_Init.c MagiDoor.h)
+add_library(mdoor STATIC ${SOURCE_FILES})
+target_include_directories(mdoor PUBLIC $<BUILD_INTERFACE:${HEADERS_DIR}>)

+ 22 - 0
MagiDoor/LICENSE

@@ -0,0 +1,22 @@
+Copyright (c) 2019, Andrew Pamment
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 378 - 0
MagiDoor/MD_AnsiCons.c

@@ -0,0 +1,378 @@
+#include <windows.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <io.h>
+
+#ifndef FOREGROUND_MASK
+# define FOREGROUND_MASK (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN)
+#endif
+
+#ifndef BACKGROUND_MASK
+# define BACKGROUND_MASK (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN)
+#endif
+
+int ansi_write(FILE* fp, const char* buf, int len) {
+    static int first = 1;
+    static int state = 0;
+    static int n;
+    static int v[6];
+    static COORD saved_coord = { 0, 0 };
+    int type;
+    HANDLE handle = INVALID_HANDLE_VALUE;
+    static WORD attr;
+    DWORD written, csize;
+    CONSOLE_CURSOR_INFO cci;
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+    COORD coord;
+    const char* ptr = buf;
+    int w, h;
+    if (fp == stdout) {
+        type = 0;
+    }
+    else if (fp == stderr) {
+        type = 1;
+    }
+    else {
+        type = 0;
+    }
+
+    handle = (HANDLE)_get_osfhandle(fileno(fp));
+    GetConsoleScreenBufferInfo(handle, &csbi);
+    attr = csbi.wAttributes;
+  
+    int z = 0;
+
+    for (z = 0; z < len; z++) {
+        if (state == 0) {
+            if (ptr[z] == '\033') {
+                state = 1;
+                continue;
+            }
+            else {
+                fputc(ptr[z], fp);
+            }
+        }
+        else if (state == 1) {
+            if (ptr[z] == '[') {
+                state = 2;
+            }
+            else {
+                state = 0;
+            }
+        } else if (state == 2) {
+            n = 0;
+            for (int j = 0; j < 6; j++) {
+                v[j] = 0;
+            }
+            state = 3;
+        }
+        if (state == 3) {
+            if (ptr[z] == ';') {
+                if (n < 6) {
+                    n++;
+                }
+                continue;
+            } else if (isdigit(ptr[z])) {
+                if (n == 0) {
+                    n = 1;
+                }
+                v[n-1] = v[n-1] * 10 + (ptr[z] - '0');
+                continue;
+            }
+            else {
+                state = 4;
+            }
+        }
+        if (state == 4) {
+            state = 0;
+            switch (ptr[z]) {
+            case 'h':
+                for (int i = 0; i < n; i++) {
+                    switch (v[i]) {
+                    case 3:
+                        GetConsoleScreenBufferInfo(handle, &csbi);
+                        w = csbi.dwSize.X;
+                        h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+                        csize = w * (h + 1);
+                        coord.X = 0;
+                        coord.Y = csbi.srWindow.Top;
+                        FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
+                        FillConsoleOutputAttribute(handle, csbi.wAttributes, csize, coord, &written);
+                        SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
+                        csbi.dwSize.X = 132;
+                        SetConsoleScreenBufferSize(handle, csbi.dwSize);
+                        csbi.srWindow.Right = csbi.srWindow.Left + 131;
+                        SetConsoleWindowInfo(handle, TRUE, &csbi.srWindow);
+                        break;
+                    case 5:
+                        attr =
+                            ((attr & FOREGROUND_MASK) << 4) |
+                            ((attr & BACKGROUND_MASK) >> 4);
+                        SetConsoleTextAttribute(handle, attr);
+                        break;
+                    case 9:
+                        break;
+                    case 25:
+                        GetConsoleCursorInfo(handle, &cci);
+                        cci.bVisible = TRUE;
+                        SetConsoleCursorInfo(handle, &cci);
+                        break;
+                    case 47:
+                        coord.X = 0;
+                        coord.Y = 0;
+                        SetConsoleCursorPosition(handle, coord);
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                
+                break;
+            case 'l':
+                for (int i = 0; i < n; i++) {
+                    switch (v[i]) {
+                    case 3:
+                        GetConsoleScreenBufferInfo(handle, &csbi);
+                        w = csbi.dwSize.X;
+                        h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+                        csize = w * (h + 1);
+                        coord.X = 0;
+                        coord.Y = csbi.srWindow.Top;
+                        FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
+                        FillConsoleOutputAttribute(handle, csbi.wAttributes, csize, coord, &written);
+                        SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
+                        csbi.srWindow.Right = csbi.srWindow.Left + 79;
+                        SetConsoleWindowInfo(handle, TRUE, &csbi.srWindow);
+                        csbi.dwSize.X = 80;
+                        SetConsoleScreenBufferSize(handle, csbi.dwSize);
+                        break;
+                    case 5:
+                        attr =
+                            ((attr & FOREGROUND_MASK) << 4) |
+                            ((attr & BACKGROUND_MASK) >> 4);
+                        SetConsoleTextAttribute(handle, attr);
+                        break;
+                    case 25:
+                        GetConsoleCursorInfo(handle, &cci);
+                        cci.bVisible = FALSE;
+                        SetConsoleCursorInfo(handle, &cci);
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                break;
+            case 'm':
+                for (int i = 0; i < n; i++) {
+                    if (v[i] == -1 || v[i] == 0) {
+                        attr &= ~(FOREGROUND_INTENSITY);
+                        attr |= FOREGROUND_MASK;
+                        attr &= ~(BACKGROUND_MASK);
+                    }
+                    else if (v[i] == 1)
+                        attr |= FOREGROUND_INTENSITY;
+                    else if (v[i] == 4)
+                        attr |= FOREGROUND_INTENSITY;
+                    else if (v[i] == 5)
+                        attr |= FOREGROUND_INTENSITY;
+                    else if (v[i] == 7)
+                        attr =
+                        ((attr & FOREGROUND_MASK) << 4) |
+                        ((attr & BACKGROUND_MASK) >> 4);
+                    else if (v[i] == 10)
+                        ; // symbol on
+                    else if (v[i] == 11)
+                        ; // symbol off
+                    else if (v[i] == 22)
+                        attr &= ~FOREGROUND_INTENSITY;
+                    else if (v[i] == 24)
+                        attr &= ~FOREGROUND_INTENSITY;
+                    else if (v[i] == 25)
+                        attr &= ~FOREGROUND_INTENSITY;
+                    else if (v[i] == 27)
+                        attr =
+                        ((attr & FOREGROUND_MASK) << 4) |
+                        ((attr & BACKGROUND_MASK) >> 4);
+                    else if (v[i] >= 30 && v[i] <= 37) {
+                        attr = (attr & (BACKGROUND_MASK | FOREGROUND_INTENSITY));
+                        if ((v[i] - 30) & 1)
+                            attr |= FOREGROUND_RED;
+                        if ((v[i] - 30) & 2)
+                            attr |= FOREGROUND_GREEN;
+                        if ((v[i] - 30) & 4)
+                            attr |= FOREGROUND_BLUE;
+                    }
+                    //else if (v[i] == 39)
+                    //attr = (~attr & BACKGROUND_MASK);
+                    else if (v[i] >= 40 && v[i] <= 47) {
+                        attr = (attr & (FOREGROUND_MASK | BACKGROUND_INTENSITY));
+                        if ((v[i] - 40) & 1)
+                            attr |= BACKGROUND_RED;
+                        if ((v[i] - 40) & 2)
+                            attr |= BACKGROUND_GREEN;
+                        if ((v[i] - 40) & 4)
+                            attr |= BACKGROUND_BLUE;
+                    }
+                    else if (v[i] >= 90 && v[i] <= 97) {
+                        attr = (attr & BACKGROUND_MASK) | FOREGROUND_INTENSITY;
+                        if ((v[i] - 90) & 1)
+                            attr |= FOREGROUND_RED;
+                        if ((v[i] - 90) & 2)
+                            attr |= FOREGROUND_GREEN;
+                        if ((v[i] - 90) & 4)
+                            attr |= FOREGROUND_BLUE;
+                    }
+                    else if (v[i] >= 100 && v[i] <= 107) {
+                        attr = (attr & FOREGROUND_MASK) | BACKGROUND_INTENSITY;
+                        if ((v[i] - 100) & 1)
+                            attr |= BACKGROUND_RED;
+                        if ((v[i] - 100) & 2)
+                            attr |= BACKGROUND_GREEN;
+                        if ((v[i] - 100) & 4)
+                            attr |= BACKGROUND_BLUE;
+                    }
+                    //else if (v[i] == 49)
+                    //attr = (~attr & FOREGROUND_MASK);
+
+                }
+                SetConsoleTextAttribute(handle, attr);
+                break;
+            case 'K':
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                coord = csbi.dwCursorPosition;
+                switch (v[0]) {
+                default:
+                case 0:
+                    csize = csbi.dwSize.X - coord.X;
+                    break;
+                case 1:
+                    csize = coord.X;
+                    coord.X = 0;
+                    break;
+                case 2:
+                    csize = csbi.dwSize.X;
+                    coord.X = 0;
+                    break;
+                }
+                FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
+                FillConsoleOutputAttribute(handle, attr, csize, coord, &written);
+                SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
+                break;
+            case 'J':
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                w = csbi.dwSize.X;
+                h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+                coord = csbi.dwCursorPosition;
+                switch (v[0]) {
+                default:
+                case 0:
+                    csize = w * (h - coord.Y) - coord.X;
+                    coord.X = 0;
+                    break;
+                case 1:
+                    csize = w * coord.Y + coord.X;
+                    coord.X = 0;
+                    coord.Y = csbi.srWindow.Top;
+                    break;
+                case 2:
+                    csize = w * (h + 1);
+                    coord.X = 0;
+                    coord.Y = csbi.srWindow.Top;
+                    break;
+                }
+                FillConsoleOutputCharacter(handle, ' ', csize, coord, &written);
+                FillConsoleOutputAttribute(handle, attr, csize, coord, &written);
+                SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
+                break;
+            case 'H':
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                coord = csbi.dwCursorPosition;
+                if (v[0] != -1) {
+                    if (v[1] != -1) {
+                        coord.Y = csbi.srWindow.Top + v[0] - 1;
+                        coord.X = v[1] - 1;
+                    }
+                    else
+                        coord.X = v[0] - 1;
+                }
+                else {
+                    coord.X = 0;
+                    coord.Y = csbi.srWindow.Top;
+                }
+                if (coord.X < csbi.srWindow.Left)
+                    coord.X = csbi.srWindow.Left;
+                else if (coord.X > csbi.srWindow.Right)
+                    coord.X = csbi.srWindow.Right;
+                if (coord.Y < csbi.srWindow.Top)
+                    coord.Y = csbi.srWindow.Top;
+                else if (coord.Y > csbi.srWindow.Bottom)
+                    coord.Y = csbi.srWindow.Bottom;
+                SetConsoleCursorPosition(handle, coord);
+                break;
+            case 'A': // Move up
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                coord = csbi.dwCursorPosition;
+                if (n > 0) {
+                    coord.Y = coord.Y - v[0];
+                }
+                else {
+                    coord.Y = coord.Y - 1;
+                }
+                if (coord.Y < csbi.srWindow.Top) coord.Y = csbi.srWindow.Top;
+                SetConsoleCursorPosition(handle, coord);
+                SetConsoleTextAttribute(handle, attr);
+                break;
+            case 'B': // Move down
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                coord = csbi.dwCursorPosition;
+                if (n > 0) {
+                    coord.Y = coord.Y + v[0];
+                }
+                else {
+                    coord.Y = coord.Y + 1;
+                }
+                if (coord.Y > csbi.srWindow.Bottom) coord.Y = csbi.srWindow.Bottom;
+                SetConsoleCursorPosition(handle, coord);
+                SetConsoleTextAttribute(handle, attr);
+                break;
+            case 'C': // Move forward / right
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                coord = csbi.dwCursorPosition;
+                if (n > 0) {
+                    coord.X = coord.X + v[0];
+                }
+                else {
+                    coord.X = coord.X + 1;
+                }
+                if (coord.X > csbi.srWindow.Right) coord.X = csbi.srWindow.Right;
+                SetConsoleCursorPosition(handle, coord);
+                SetConsoleTextAttribute(handle, attr);
+                break;
+            case 'D': // Move backward / left
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                coord = csbi.dwCursorPosition;
+                if (n > 0) {
+                    coord.X = coord.X - v[0];
+                }
+                else {
+                    coord.X = coord.X - 1;
+                }
+                if (coord.X < csbi.srWindow.Left) coord.X = csbi.srWindow.Left;
+                SetConsoleCursorPosition(handle, coord);
+                SetConsoleTextAttribute(handle, attr);
+                break;
+            case 's':
+                GetConsoleScreenBufferInfo(handle, &csbi);
+                saved_coord = csbi.dwCursorPosition;
+                break;
+            case 'u':
+                SetConsoleCursorPosition(handle, saved_coord);
+                break;
+            default:
+                break;
+            }
+        }
+    }
+    return z;
+}

+ 4 - 0
MagiDoor/MD_AnsiCons.h

@@ -0,0 +1,4 @@
+#pragma once
+#include <stdio.h>
+
+extern int ansi_write(FILE* fp, const char* buf, int len);

+ 97 - 0
MagiDoor/MD_Getc.c

@@ -0,0 +1,97 @@
+#include <errno.h>
+#include <stdio.h>
+#if defined(_MSC_VER) || defined(WIN32)
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include "MagiDoor.h"
+
+extern time_t mdtimeout;
+extern time_t mdtimeremaining;
+
+char md_getc() {
+    char c;
+    ssize_t ret;
+    while (1) {
+        if (mdcontrol.socket == -1) {
+            ret = read(STDIN_FILENO, &c, 1);
+        } else {
+            ret = recv(mdcontrol.socket, &c, 1, 0);
+        }
+        if (ret == 0) {
+            md_exit(0);
+        }
+#if defined(_MSC_VER) || defined(WIN32)
+        if (ret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) {
+#else
+        if (ret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+#endif
+            if (mdtimeout <= time(NULL)) {
+                md_printf("\r\nIdle timeout!\r\n");
+                md_exit(0);
+            }
+            if (mdtimeremaining <= time(NULL)) {
+                md_printf("\r\nOut of time!\r\n");
+                md_exit(0);
+            }
+            usleep(100);
+            continue;
+        }
+        mdtimeout = time(NULL) + 900;
+        return c;
+    }
+}
+
+char md_get_answer(char *options) {
+    char c;
+    c = md_getc();
+    while (strchr(options, c) == NULL) {
+        c = md_getc();
+    }
+    return c;
+}
+
+int md_getstring(char *ptr, int maxlen, char minchar, char maxchar) {
+    char c;
+    int len = 0;
+    static char lastc = 'x';
+
+    *ptr = '\0';
+    
+    while (len < maxlen) {
+        c = md_getc();
+        if (c == '\n' || c == '\0') {
+            lastc = c;
+            if (lastc == '\r') {
+                continue;
+            } else {
+                return len;
+            }
+        }
+        if (c == '\r') {
+            lastc = c;
+            return len;
+        } 
+        if (c == '\b' || c == 127) {
+            if (len > 0) {
+                md_printf("\b \b");
+                len--;
+                ptr[len] = '\0';
+            }
+            lastc = c;
+            continue;
+        }
+        if (c >= minchar && c <= maxchar) {
+            ptr[len++] = c;
+            ptr[len] = '\0';
+            md_putchar(c);
+        }
+        lastc = c;
+    }
+
+    return len;
+}

+ 251 - 0
MagiDoor/MD_Init.c

@@ -0,0 +1,251 @@
+#include <stdio.h>
+#if defined(WIN32) || defined(_MSC_VER)
+#include <winsock2.h>
+#else
+#include <termios.h>
+#include <signal.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "MagiDoor.h"
+
+
+#if defined(WIN32) || defined(_MSC_VER)
+#define PATH_SEP '\\'
+#else
+#define PATH_SEP '/'
+#endif
+
+
+MDDoorControl_t mdcontrol;
+
+#if defined(WIN32) || defined(_MSC_VER)
+#else
+struct termios ttysave;
+#endif
+
+time_t mdtimeout;
+time_t mdtimeremaining;
+
+static void md_cfg_read_line(char *buffer, int len, FILE *fptr) {
+    fgets(buffer, len, fptr);
+    if (buffer[strlen(buffer) - 1] == '\n') {
+        buffer[strlen(buffer) - 1] = '\0';
+    }
+    if (buffer[strlen(buffer) - 1] == '\r') {
+        buffer[strlen(buffer) - 1] = '\0';
+    }    
+}
+
+int read_door32(const char *dropfile) {
+    FILE *fptr;
+    char buffer[256];
+    char *ptr1;
+
+    fptr = fopen(dropfile, "r");
+    if (!fptr) {
+        return -1;
+    }
+
+	md_cfg_read_line(buffer, 256, fptr); // com type
+    md_cfg_read_line(buffer, 256, fptr); // socket handle
+    mdcontrol.socket = strtol(buffer, NULL, 10);
+    md_cfg_read_line(buffer, 256, fptr); // baud rate
+    md_cfg_read_line(buffer, 256, fptr); // BBS ID
+    md_cfg_read_line(buffer, 256, fptr); // User record pos (1 based)
+    md_cfg_read_line(buffer, 256, fptr); // User's real name
+    ptr1 = strrchr(buffer, ' ');
+    if (ptr1 != NULL) {
+        *ptr1 = '\0';
+        ptr1++;
+        strncpy(mdcontrol.user_firstname, buffer, 32);
+        strncpy(mdcontrol.user_lastname, ptr1, 32);
+    } else {
+        strncpy(mdcontrol.user_firstname, buffer, 32);
+        memset(mdcontrol.user_lastname, '\0', 32);
+    }
+    md_cfg_read_line(buffer, 256, fptr); // User's handle
+    strncpy(mdcontrol.user_alias, buffer, 32);
+
+    md_cfg_read_line(buffer, 256, fptr); // User's sec level
+    mdcontrol.user_seclevel = strtol(buffer, NULL, 10);
+ 
+    md_cfg_read_line(buffer, 256, fptr); // time left (minutes)
+    mdcontrol.user_timeleft = strtol(buffer, NULL, 10) * 60;
+
+    md_cfg_read_line(buffer, 256, fptr); // emulation
+    md_cfg_read_line(buffer, 256, fptr); // node no
+    
+    mdcontrol.node = strtol(buffer, NULL, 10);
+
+    return 0;
+}
+
+int read_doorsys(const char *dropfile) {
+    FILE *fptr;
+    char buffer[256];
+    char *ptr1;
+
+    fptr = fopen(dropfile, "r");
+    if (!fptr) {
+        return -1;
+    }
+    
+    md_cfg_read_line(buffer, 256, fptr); // Comport
+    md_cfg_read_line(buffer, 256, fptr); // Ebaud
+    md_cfg_read_line(buffer, 256, fptr); // data bits
+    md_cfg_read_line(buffer, 256, fptr); // node number
+    mdcontrol.node = strtol(buffer, NULL, 10);
+
+    md_cfg_read_line(buffer, 256, fptr); // Lbaud
+    md_cfg_read_line(buffer, 256, fptr); // Screen Display
+    md_cfg_read_line(buffer, 256, fptr); // Printer On
+    md_cfg_read_line(buffer, 256, fptr); // Page Bell
+    md_cfg_read_line(buffer, 256, fptr); // Caller alarm
+    md_cfg_read_line(buffer, 256, fptr); // User Name
+    ptr1 = strrchr(buffer, ' ');
+    if (ptr1 != NULL) {
+        *ptr1 = '\0';
+        ptr1++;
+        strncpy(mdcontrol.user_firstname, buffer, 32);
+        strncpy(mdcontrol.user_lastname, ptr1, 32);
+    } else {
+        strncpy(mdcontrol.user_firstname, buffer, 32);
+        memset(mdcontrol.user_lastname, '\0', 32);
+    }
+    md_cfg_read_line(buffer, 256, fptr); // Location
+    strncpy(mdcontrol.user_location, buffer, 32);
+
+    md_cfg_read_line(buffer, 256, fptr); // voice phone
+    md_cfg_read_line(buffer, 256, fptr); // data phone
+    md_cfg_read_line(buffer, 256, fptr); // password
+    md_cfg_read_line(buffer, 256, fptr); // sec level
+    mdcontrol.user_seclevel = strtol(buffer, NULL, 10);
+
+    md_cfg_read_line(buffer, 256, fptr); // calls
+    md_cfg_read_line(buffer, 256, fptr); // last login
+    md_cfg_read_line(buffer, 256, fptr); // time left (seconds)
+    mdcontrol.user_timeleft = strtol(buffer, NULL, 10);
+
+    md_cfg_read_line(buffer, 256, fptr); // time left (minutes)
+    md_cfg_read_line(buffer, 256, fptr); // graphics
+    md_cfg_read_line(buffer, 256, fptr); // screen len
+    md_cfg_read_line(buffer, 256, fptr); // usermode
+    md_cfg_read_line(buffer, 256, fptr); // extra 1
+    md_cfg_read_line(buffer, 256, fptr); // extra 2
+    md_cfg_read_line(buffer, 256, fptr); // expiry date
+    md_cfg_read_line(buffer, 256, fptr); // rec num
+    md_cfg_read_line(buffer, 256, fptr); // protocol
+    md_cfg_read_line(buffer, 256, fptr); // uploads
+    md_cfg_read_line(buffer, 256, fptr); // downloads
+    md_cfg_read_line(buffer, 256, fptr); // Lim down k
+    md_cfg_read_line(buffer, 256, fptr); // Lim down k2
+    md_cfg_read_line(buffer, 256, fptr); // DOB
+    md_cfg_read_line(buffer, 256, fptr); // User Base
+    md_cfg_read_line(buffer, 256, fptr); // Message Base
+    md_cfg_read_line(buffer, 256, fptr); // Sysop Name
+    strncpy(mdcontrol.sysop_name, buffer, 32);
+
+    md_cfg_read_line(buffer, 256, fptr); // Handle
+    strncpy(mdcontrol.user_alias, buffer, 32);
+
+    md_cfg_read_line(buffer, 256, fptr); // Next Event
+    md_cfg_read_line(buffer, 256, fptr); // Error Free
+    md_cfg_read_line(buffer, 256, fptr); // Always N
+    md_cfg_read_line(buffer, 256, fptr); // Always Y
+    md_cfg_read_line(buffer, 256, fptr); // Def Colour
+    md_cfg_read_line(buffer, 256, fptr); // Always 0
+    md_cfg_read_line(buffer, 256, fptr); // Last Login 2
+    md_cfg_read_line(buffer, 256, fptr); // Time Login
+    md_cfg_read_line(buffer, 256, fptr); // Last Login Time
+    md_cfg_read_line(buffer, 256, fptr); // Max Integer
+    md_cfg_read_line(buffer, 256, fptr); // Downs today
+    md_cfg_read_line(buffer, 256, fptr); // Upload K
+    md_cfg_read_line(buffer, 256, fptr); // Download K
+    md_cfg_read_line(buffer, 256, fptr); // Comment
+    md_cfg_read_line(buffer, 256, fptr); // Always 0
+    md_cfg_read_line(buffer, 256, fptr); // posted
+
+    fclose(fptr);
+
+    return 0;
+}
+
+#if !defined(WIN32) && !defined(_MSC_VER)
+
+void md_sighuphandler(int i)
+{
+    md_exit(-1);
+}
+
+#endif
+
+
+void md_exit(int exitcode) {
+    if (mdcontrol.socket == -1) {
+#if !defined(WIN32) && !defined(_MSC_VER)
+         tcsetattr(STDIN_FILENO, TCSANOW, &ttysave);
+#endif
+    } else {
+        // nothing
+    }
+    exit(exitcode);
+}
+
+void md_init(const char *dropfile, int socket) {
+    char *filename = strrchr(dropfile, PATH_SEP);
+#if !defined(WIN32) && !defined(_MSC_VER)
+    struct termios ttystate;
+    signal(SIGHUP, &md_sighuphandler);
+
+#endif
+    int ret = -1;
+
+    mdcontrol.socket = socket;
+
+    if (filename == NULL) {
+        filename = (char *)dropfile;
+    } else {
+        filename++;
+    }
+
+    if (strcasecmp(filename, "door.sys") == 0) {
+        ret = read_doorsys(dropfile);
+    } else if (strcasecmp(filename, "door32.sys") == 0) {
+        ret = read_door32(dropfile);
+    } else {
+        fprintf(stderr, "Unsupported dropfile: %s\n", filename);
+        exit(-1);
+    }
+
+    if (ret == -1) {
+        fprintf(stderr, "Unable to open dropfile: %s\n", dropfile);
+        exit(-1);
+    }
+
+    if (mdcontrol.socket == -1) {
+#if !defined(WIN32) && !defined(_MSC_VER)
+        tcgetattr(STDIN_FILENO, &ttystate);
+        ttysave = ttystate;
+
+	    ttystate.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
+	    ttystate.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | ISTRIP | IXON | PARMRK);
+	    ttystate.c_oflag &= ~OPOST;
+	    ttystate.c_cc[VMIN] = 1;
+	    ttystate.c_cc[VTIME] = 0;
+
+        tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+#endif
+    } else {
+#if defined(WIN32) || defined(_MSC_VER)
+        WSADATA wsa;
+
+        WSAStartup(WINSOCK_VERSION, &wsa);
+#endif        
+    }
+    mdtimeremaining = time(NULL) + mdcontrol.user_timeleft;
+    mdtimeout = time(NULL) + 900;
+    return;
+}

+ 142 - 0
MagiDoor/MD_Printf.c

@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#if defined(_MSC_VER) || defined(WIN32)
+#include <winsock2.h>
+#include "MD_AnsiCons.h"
+#else
+#include <sys/socket.h>
+#endif
+#include "MagiDoor.h"
+
+void md_putchar(char c) {
+#if defined(_MSC_VER) || defined(WIN32)
+    ansi_write(stdout, &c, 1);
+#endif
+    if (mdcontrol.socket == -1) {
+        write(STDOUT_FILENO, &c, 1);
+    } else {
+        send(mdcontrol.socket, &c, 1, 0);
+    }
+}
+
+void md_set_cursor(int y, int x) {
+    md_printf("\x1b[%d;%dH", y, x);
+}
+
+void md_clr_scr() {
+    md_printf("\x1b[2J\x1b[1;1H");
+}
+
+void md_printcode(char *code) {
+    char *part;
+    int bright = 0;
+    int colour = 0;
+    int bgcolour = 0;
+    char codebuffer[11];
+    int i;
+
+    part = strtok(code, " ");
+    if (part != NULL) {
+        if (strcmp(part, "bright") == 0) {
+            bright = 1;
+        } else if (strcmp(part, "black") == 0) {
+            colour = 0;
+        } else if (strcmp(part, "red") == 0) {
+            colour = 1;
+        } else if (strcmp(part, "green") == 0) {
+            colour = 2;
+        } else if (strcmp(part, "yellow") == 0) {
+            colour = 3;
+        } else if (strcmp(part, "blue") == 0) {
+            colour = 4;
+        } else if (strcmp(part, "magenta") == 0) {
+            colour = 5;
+        } else if (strcmp(part, "cyan") == 0) {
+            colour = 6;
+        } else if (strcmp(part, "white") == 0) {
+            colour = 7;
+        }
+        part = strtok(NULL, " ");
+        if (part != NULL) {
+            if (bright == 0) {
+                bgcolour = colour;
+                colour = 0;
+            }
+            if (strcmp(part, "bright") == 0) {
+                bright = 1;
+                part = strtok(NULL, " ");
+            }
+            if (part != NULL) {
+
+                if (strcmp(part, "black") == 0) {
+                    colour = 0;
+                } else if (strcmp(part, "red") == 0) {
+                    colour = 1;
+                } else if (strcmp(part, "green") == 0) {
+                    colour = 2;
+                } else if (strcmp(part, "yellow") == 0) {
+                    colour = 3;
+                } else if (strcmp(part, "blue") == 0) {
+                    colour = 4;
+                } else if (strcmp(part, "magenta") == 0) {
+                    colour = 5;
+                } else if (strcmp(part, "cyan") == 0) {
+                    colour = 6;
+                } else if (strcmp(part, "white") == 0) {
+                    colour = 7;
+                }                
+            }
+        }
+    }
+
+    snprintf(codebuffer, 11, "\x1b[%d;4%d;3%dm", bright, bgcolour, colour);
+
+    for (i=0;i<10;i++) {
+        md_putchar(codebuffer[i]);
+    }
+}
+
+void md_printf(const char *fmt, ...) {
+    char buffer[4096];
+    char codebuf[128];
+    va_list ap;
+
+    va_start(ap, fmt);
+    vsnprintf(buffer, sizeof buffer, fmt, ap);
+	va_end(ap);
+
+    char *ptr;
+    char *cbptr;
+    ptr = buffer;
+    while (*ptr != '\0') {
+        if (*ptr == '`') {
+            ptr++;
+            if (*ptr == '`') {
+                md_putchar('`');
+                ptr++;
+                continue;
+            } else if (*ptr == '\0') {
+                break;
+            }
+            cbptr = codebuf;
+            while(*ptr != '`' && *ptr != '\0' && cbptr - codebuf < 127) {
+                *cbptr = *ptr;
+                ptr++;
+                cbptr++;
+                *cbptr = '\0';
+            }
+
+            md_printcode(codebuf);
+
+            if (*ptr == '\0') {
+                break;
+            }
+            ptr++;
+            continue;
+        }
+        md_putchar(*ptr);
+        ptr++;
+    }
+}

+ 43 - 0
MagiDoor/MD_Sendfile.c

@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <ctype.h>
+#include "MagiDoor.h"
+
+void md_sendfile(const char *filename, int pause) {
+    FILE *fptr;
+    char c, d;
+    int lines = 0;
+    char lastch = 'x';
+    
+    fptr = fopen(filename, "r");
+    if (fptr != NULL) {
+        c = fgetc(fptr);
+        while (!feof(fptr) && c != 0x1a) {
+            if (c == '\n') {
+                lines++;
+                if (lastch != '\r') {
+                    md_printf("\r\n");
+                } else {
+                    md_printf("\n");
+                }
+                if (lines == 22 && pause == TRUE) {
+                    md_printf("More (Y/N)");
+                    d = md_getc();
+                    if (tolower(d) == 'n') {
+                        fclose(fptr);
+                        return;
+                    }
+                    md_printf("\r\n");
+                    lines = 0;
+                    
+                }
+            } else {
+                md_putchar(c);
+            }
+            lastch = c;
+            c = fgetc(fptr);
+        }
+        fclose(fptr);
+        return;
+    }
+    return;
+}

+ 36 - 0
MagiDoor/MagiDoor.h

@@ -0,0 +1,36 @@
+#ifndef __MAGIDOOR_H__
+#define __MAGIDOOR_H__
+
+#include <stdint.h>
+
+#define MAGIDOOR_VERSION_MAJOR 1
+#define MAGIDOOR_VERSION_MINOR 2
+
+#define TRUE  1
+#define FALSE 0
+
+typedef struct MDDoorControl {
+    char user_alias[32];
+    char user_firstname[32];
+    char user_lastname[32];
+    int user_timeleft;
+    char sysop_name[32];
+    int node;
+    char user_location[32];
+    int user_seclevel;
+    int socket;
+} MDDoorControl_t;
+
+extern MDDoorControl_t mdcontrol;
+
+extern void md_init(const char *dropfile, int socket);
+extern void md_exit(int exitcode);
+extern void md_putchar(char c);
+extern void md_printf(const char *fmt, ...);
+extern char md_getc();
+extern int md_getstring(char *ptr, int maxlen, char minchar, char maxchar);
+extern void md_sendfile(const char *filename, int pause);
+extern void md_clr_scr();
+extern void md_set_cursor(int y, int x);
+extern char md_get_answer(char *options);
+#endif

+ 9 - 0
MagiDoor/buildwin.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+i686-w64-mingw32-gcc -c MD_Init.c
+i686-w64-mingw32-gcc -c MD_Printf.c
+i686-w64-mingw32-gcc -c MD_Getc.c
+i686-w64-mingw32-gcc -c MD_Sendfile.c
+i686-w64-mingw32-gcc -c MD_AnsiCons.c
+i686-w64-mingw32-gcc -shared -o mdoor.dll *.o -lws2_32 -Wl,--out-implib,libmdoor.a
+
+rm *.o